From 5b36f683ab76e9bd4d19ecf3d216003267aa1807 Mon Sep 17 00:00:00 2001 From: Matt Moore Date: Thu, 2 Dec 2021 09:17:29 -0800 Subject: [PATCH] Drop OpenAPI for the client/server. We serve a single handler, so OpenAPI creates a ton of overhead for our use case. This change switches to a relatively simple http.Handler based API, and a hand-rolled API client. This also contains unit testing of the client/server using a trivial OIDC implementation and ephemeralca. Signed-off-by: Matt Moore --- .gitattributes | 2 - .github/workflows/main.yml | 3 - Makefile | 23 +- cmd/app/serve.go | 60 +- config/deployment.yaml | 3 +- go.mod | 17 +- go.sum | 222 ------- openapi.yaml | 116 ---- pkg/api/api_test.go | 190 ++++++ pkg/api/ca.go | 131 +++- pkg/api/client.go | 167 +++++ pkg/api/error.go | 53 +- .../client_test.go => api/options_test.go} | 18 +- pkg/challenges/challenges.go | 17 +- pkg/client/client.go | 89 --- pkg/config/config.go | 52 +- pkg/generated/client/fulcio_client.go | 127 ---- .../client/operations/operations_client.go | 93 --- .../operations/signing_cert_parameters.go | 167 ----- .../operations/signing_cert_responses.go | 261 -------- pkg/generated/models/certificate_request.go | 246 ------- pkg/generated/models/error.go | 69 -- .../restapi/configure_fulcio_server.go | 251 ------- pkg/generated/restapi/doc.go | 34 - pkg/generated/restapi/embedded_spec.go | 396 ----------- pkg/generated/restapi/fulcioHomePage.html | 30 - .../restapi/operations/fulcio_server_api.go | 351 ---------- .../restapi/operations/signing_cert.go | 87 --- .../operations/signing_cert_parameters.go | 101 --- .../operations/signing_cert_responses.go | 329 --------- .../operations/signing_cert_urlbuilder.go | 103 --- pkg/generated/restapi/server.go | 629 ------------------ 32 files changed, 560 insertions(+), 3877 deletions(-) delete mode 100644 openapi.yaml create mode 100644 pkg/api/api_test.go create mode 100644 pkg/api/client.go rename pkg/{client/client_test.go => api/options_test.go} (88%) delete mode 100644 pkg/client/client.go delete mode 100644 pkg/generated/client/fulcio_client.go delete mode 100644 pkg/generated/client/operations/operations_client.go delete mode 100644 pkg/generated/client/operations/signing_cert_parameters.go delete mode 100644 pkg/generated/client/operations/signing_cert_responses.go delete mode 100644 pkg/generated/models/certificate_request.go delete mode 100644 pkg/generated/models/error.go delete mode 100644 pkg/generated/restapi/configure_fulcio_server.go delete mode 100644 pkg/generated/restapi/doc.go delete mode 100644 pkg/generated/restapi/embedded_spec.go delete mode 100644 pkg/generated/restapi/fulcioHomePage.html delete mode 100644 pkg/generated/restapi/operations/fulcio_server_api.go delete mode 100644 pkg/generated/restapi/operations/signing_cert.go delete mode 100644 pkg/generated/restapi/operations/signing_cert_parameters.go delete mode 100644 pkg/generated/restapi/operations/signing_cert_responses.go delete mode 100644 pkg/generated/restapi/operations/signing_cert_urlbuilder.go delete mode 100644 pkg/generated/restapi/server.go diff --git a/.gitattributes b/.gitattributes index a3e07d93b..e69de29bb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +0,0 @@ -/pkg/generated/** linguist-generated -/pkg/generated/restapi/configure_fulcio_server.go -linguist-generated diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 54f4b0958..43090ceec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,9 +33,6 @@ jobs: with: go-version: ${{ env.GOVERSION }} - - name: Validate OpenAPI with Swagger - run: make validate-openapi - - name: Build run: make -C $GITHUB_WORKSPACE all - name: Test diff --git a/Makefile b/Makefile index d845fe744..54c6db503 100644 --- a/Makefile +++ b/Makefile @@ -19,9 +19,8 @@ all: fulcio # Ensure Make is run with bash shell as some syntax below is bash-specific SHELL:=/usr/bin/env bash -GENSRC = pkg/generated/models/%.go pkg/generated/restapi/%.go OPENAPIDEPS = openapi.yaml -SRCS = $(shell find cmd -iname "*.go") $(shell find pkg -iname "*.go"|grep -v pkg/generated) pkg/generated/restapi/configure_fulcio_server.go $(GENSRC) +SRCS = $(shell find cmd -iname "*.go") $(shell find pkg -iname "*.go") TOOLS_DIR := hack/tools TOOLS_BIN_DIR := $(abspath $(TOOLS_DIR)/bin) BIN_DIR := $(abspath $(ROOT_DIR)/bin) @@ -44,16 +43,6 @@ endif SERVER_PKG=github.com/sigstore/fulcio/cmd/app SERVER_LDFLAGS="-X $(SERVER_PKG).gitVersion=$(GIT_VERSION) -X $(SERVER_PKG).gitCommit=$(GIT_HASH) -X $(SERVER_PKG).gitTreeState=$(GIT_TREESTATE) -X $(SERVER_PKG).buildDate=$(BUILD_DATE)" - -# Binaries -SWAGGER := $(TOOLS_BIN_DIR)/swagger - -$(GENSRC): $(SWAGGER) $(OPENAPIDEPS) - $(SWAGGER) generate server -f openapi.yaml -q -r COPYRIGHT.txt -t pkg/generated --exclude-main -A fulcio_server --exclude-spec --flag-strategy=pflag --principal github.com/coreos/go-oidc/v3/oidc.IDToken --additional-initialism=SCT - $(SWAGGER) generate client -f openapi.yaml -q -r COPYRIGHT.txt -t pkg/generated --principal github.com/coreos/go-oidc/v3/oidc.IDToken - -# this exists to override pattern match rule above since this file is in the generated directory but should not be treated as generated code -pkg/generated/restapi/configure_fulcio_server.go: $(OPENAPIDEPS) lint: @@ -82,10 +71,6 @@ debug: docker-compose -f docker-compose.yml -f docker-compose.debug.yml up fulcio-server-debug -.PHONY: validate-openapi -validate-openapi: $(SWAGGER) - $(SWAGGER) validate openapi.yaml - ## -------------------------------------- ## Modules ## -------------------------------------- @@ -104,9 +89,3 @@ dist: mkdir -p dist docker run -it -v $(PWD):/go/src/sigstore/fulcio -w /go/src/sigstore/fulcio golang:1.16.6 /bin/bash -c "GOOS=linux GOARCH=amd64 go build -trimpath -o dist/fulcio-server-linux-amd64" -## -------------------------------------- -## Tooling Binaries -## -------------------------------------- - -$(SWAGGER): $(TOOLS_DIR)/go.mod - cd $(TOOLS_DIR); go build -trimpath -tags=tools -o $(TOOLS_BIN_DIR)/swagger github.com/go-swagger/go-swagger/cmd/swagger diff --git a/cmd/app/serve.go b/cmd/app/serve.go index 6f6beb772..3bc499f41 100644 --- a/cmd/app/serve.go +++ b/cmd/app/serve.go @@ -19,8 +19,8 @@ import ( "flag" "fmt" "net/http" + "os" - "github.com/go-openapi/loads" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/sigstore/fulcio/pkg/api" certauth "github.com/sigstore/fulcio/pkg/ca" @@ -29,8 +29,6 @@ import ( googlecav1beta1 "github.com/sigstore/fulcio/pkg/ca/googleca/v1beta1" "github.com/sigstore/fulcio/pkg/ca/x509ca" "github.com/sigstore/fulcio/pkg/config" - "github.com/sigstore/fulcio/pkg/generated/restapi" - "github.com/sigstore/fulcio/pkg/generated/restapi/operations" "github.com/sigstore/fulcio/pkg/log" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -66,14 +64,6 @@ var serveCmd = &cobra.Command{ // from https://github.com/golang/glog/commit/fca8c8854093a154ff1eb580aae10276ad6b1b5f _ = flag.CommandLine.Parse([]string{}) - doc, _ := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON) - server := restapi.NewServer(operations.NewFulcioServerAPI(doc)) - defer func() { - if err := server.Shutdown(); err != nil { - log.Logger.Error(err) - } - }() - cfg, err := config.Load(viper.GetString("config-path")) if err != nil { log.Logger.Fatalf("error loading config: %v", err) @@ -110,31 +100,41 @@ var serveCmd = &cobra.Command{ log.Logger.Fatal(err) } - server.EnabledListeners = []string{"http"} + decorateHandler := func(h http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + ctx := r.Context() - server.ConfigureAPI() + // For each request, infuse context with our snapshot of the FulcioConfig. + // TODO(mattmoor): Consider periodically (every minute?) refreshing the ConfigMap + // from disk, so that we don't need to cycle pods to pick up config updates. + // Alternately we could take advantage of Knative's configmap watcher. + ctx = config.With(ctx, cfg) + ctx = api.WithCA(ctx, baseca) + ctx = api.WithCTLogURL(ctx, viper.GetString("ct-log-url")) - h := server.GetHandler() - server.SetHandler(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - // For each request, infuse context with our snapshot of the FulcioConfig. - // TODO(mattmoor): Consider periodically (every minute?) refreshing the ConfigMap - // from disk, so that we don't need to cycle pods to pick up config updates. - // Alternately we could take advantage of Knative's configmap watcher. - ctx = config.With(ctx, cfg) - ctx = api.WithCA(ctx, baseca) - ctx = api.WithCTLogURL(ctx, viper.GetString("ct-log-url")) - - h.ServeHTTP(rw, r.WithContext(ctx)) - })) + h.ServeHTTP(rw, r.WithContext(ctx)) + }) + } - http.Handle("/metrics", promhttp.Handler()) + prom := http.Server{ + Addr: ":2112", + Handler: promhttp.Handler(), + } go func() { - _ = http.ListenAndServe(":2112", nil) + _ = prom.ListenAndServe() }() - if err := server.Serve(); err != nil { + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + api := http.Server{ + Addr: ":" + port, + Handler: decorateHandler(api.NewHandler()), + } + + if err := api.ListenAndServe(); err != nil { log.Logger.Fatal(err) } }, diff --git a/config/deployment.yaml b/config/deployment.yaml index ac5ddebdb..1f83f7fda 100644 --- a/config/deployment.yaml +++ b/config/deployment.yaml @@ -42,11 +42,12 @@ spec: - containerPort: 2112 # metrics args: [ "serve", - "--host=0.0.0.0", "--port=5555", "--ca=googleca", "--gcp_private_ca_parent=$(CA_PARENT)", "--gcp_private_ca_version=v1", "--ct-log-url=http://ct-log/test", "--log_type=prod", ] env: + - name: PORT + value: "5555" - name: CA_PARENT valueFrom: configMapKeyRef: diff --git a/go.mod b/go.mod index f65470b64..d9ac97b7c 100644 --- a/go.mod +++ b/go.mod @@ -6,37 +6,26 @@ require ( cloud.google.com/go/security v1.1.0 github.com/PaesslerAG/jsonpath v0.1.1 github.com/ThalesIgnite/crypto11 v1.2.5 - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/coreos/go-oidc/v3 v3.1.0 github.com/go-chi/chi v4.1.2+incompatible - github.com/go-openapi/errors v0.20.1 - github.com/go-openapi/loads v0.21.0 - github.com/go-openapi/runtime v0.21.0 - github.com/go-openapi/spec v0.20.4 - github.com/go-openapi/strfmt v0.21.1 - github.com/go-openapi/swag v0.19.15 - github.com/go-openapi/validate v0.20.3 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.5.6 github.com/google/uuid v1.3.0 github.com/hashicorp/golang-lru v0.5.4 - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mitchellh/mapstructure v1.4.3 + github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.11.0 github.com/prometheus/common v0.29.0 // indirect github.com/prometheus/procfs v0.7.0 // indirect - github.com/rs/cors v1.8.0 github.com/sigstore/sigstore v1.0.1 github.com/spf13/cobra v1.2.1 - github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.9.0 github.com/stretchr/testify v1.7.0 - github.com/tidwall/pretty v1.2.0 // indirect go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.19.1 - golang.org/x/net v0.0.0-20210614182718-04defd469f4e + golang.org/x/text v0.3.7 // indirect google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca google.golang.org/protobuf v1.27.1 + gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/go.sum b/go.sum index b80ae0575..b4b08f85d 100644 --- a/go.sum +++ b/go.sum @@ -101,23 +101,18 @@ github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8= github.com/PaesslerAG/jsonpath v0.1.1 h1:c1/AToHQMVsduPAa4Vh6xp2U0evy4t8SWp8imEsylIk= github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/ReneKroon/ttlcache/v2 v2.9.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E= github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE= -github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -125,15 +120,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.42.1/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -307,8 +295,6 @@ github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6Uezg github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= @@ -345,10 +331,6 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= -github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= @@ -365,138 +347,18 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= -github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= -github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= -github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= -github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= -github.com/go-openapi/analysis v0.20.1 h1:zdVbw8yoD4SWZeq+cWdGgquaB0W4VrsJvDJHJND/Ktc= -github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= -github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.1 h1:j23mMDtRxMwIobkpId7sWh7Ddcx4ivaoqUbfXx5P+a8= -github.com/go-openapi/errors v0.20.1/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= -github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= -github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= -github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= -github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= -github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= -github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= -github.com/go-openapi/loads v0.21.0 h1:jYtUO4wwP7psAweisP/MDoOpdzsYEESdoPcsWjHDR68= -github.com/go-openapi/loads v0.21.0/go.mod h1:rHYve9nZrQ4CJhyeIIFJINGCg1tQpx2yJrrNo8sf1ws= -github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= -github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= -github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= -github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= -github.com/go-openapi/runtime v0.21.0 h1:giZ8eT26R+/rx6RX2MkYjZPY8vPYVKDhP/mOazrQHzM= -github.com/go-openapi/runtime v0.21.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= -github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= -github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1 h1:G6s2t5V5kGCHLVbSdZ/6lI8Wm4OzoPFkc3/cjAsKQrM= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= -github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= -github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= -github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= -github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= -github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= -github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw= -github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4= -github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-rod/rod v0.101.8/go.mod h1:N/zlT53CfSpq74nb6rOR0K8UF0SPUPBmzBnArrms+mY= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= @@ -546,7 +408,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -685,10 +546,7 @@ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -700,18 +558,14 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -725,21 +579,12 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -747,7 +592,6 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -774,9 +618,6 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= @@ -792,7 +633,6 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -805,7 +645,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -842,14 +681,9 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.m github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= @@ -908,11 +742,7 @@ github.com/prometheus/procfs v0.7.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= -github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -925,14 +755,12 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/secure-systems-lab/go-securesystemslib v0.1.0/go.mod h1:eIjBmIP8LD2MLBL/DkQWayLiz006Q4p+hCu79rvWleY= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sigstore/sigstore v1.0.1 h1:AiJAuz309uei26tRtvzV1XQorns2UogZsgs4ZQ2cYiA= github.com/sigstore/sigstore v1.0.1/go.mod h1:1+krIdtuf81/fLC8mHPt/7uwYiOg7W8k/PAR7lzKW3w= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -995,20 +823,14 @@ github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gt github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= github.com/theupdateframework/go-tuf v0.0.0-20210722233521-90e262754396 h1:j4odVZMwglHp54CYsNHd0wls+lkQzxloQU9AQjQu0W4= github.com/theupdateframework/go-tuf v0.0.0-20210722233521-90e262754396/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -1017,17 +839,11 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/ysmood/goob v0.3.0/go.mod h1:S3lq113Y91y1UBf1wj1pFOxeahvfKkCk6mTWTWbDdWs= github.com/ysmood/got v0.15.1/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY= github.com/ysmood/gotrace v0.2.2/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM= @@ -1048,17 +864,6 @@ go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3C go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5 h1:ny3p0reEpgsR2cfA5cjgwFZg3Cv/ofFh/8jbhGtz9VI= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -1090,19 +895,14 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1150,7 +950,6 @@ golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1159,7 +958,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1186,7 +984,6 @@ golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -1194,14 +991,12 @@ golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= @@ -1227,7 +1022,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1245,16 +1039,12 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1263,7 +1053,6 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1322,7 +1111,6 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1359,22 +1147,16 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1593,8 +1375,6 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= @@ -1618,8 +1398,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/openapi.yaml b/openapi.yaml deleted file mode 100644 index b655160e1..000000000 --- a/openapi.yaml +++ /dev/null @@ -1,116 +0,0 @@ -# -# Copyright 2021 The Sigstore Authors. -# -# 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. - -swagger: '2.0' -info: - version: '1.0.0' - title: Fulcio -schemes: [http, https] -host: fulcio.sigstore.dev -basePath: /api/v1 -securityDefinitions: - Bearer: - type: apiKey - in: header - name: Authorization -paths: - /signingCert: - post: - security: - - Bearer: [] - description: 'create a cert, return content with a location header (with URL to CTL entry)' - operationId: signingCert - consumes: - - application/json - produces: - - application/pem-certificate-chain - parameters: - - name: 'CertificateRequest' - in: 'body' - required: true - description: 'Request for signing certificate' - schema: - $ref: '#/definitions/CertificateRequest' - responses: - 201: - description: Generated Certificate Chain - headers: - SCT: - description: Signed Certificate Timestamp from Entry in CT Log - type: string - format: byte - schema: - type: string - 400: - $ref: '#/responses/BadRequest' - 401: - $ref: '#/responses/Unauthorized' - default: - $ref: '#/responses/InternalServerError' - -definitions: - CertificateRequest: - type: object - properties: - publicKey: - type: object - properties: - content: - type: string - format: byte - algorithm: - type: string - enum: ['ecdsa'] - required: - - content - signedEmailAddress: - type: string - format: byte - required: - - publicKey - - signedEmailAddress - Error: - type: object - properties: - code: - type: integer - message: - type: string - -responses: - BadRequest: - description: The content supplied to the server was invalid - schema: - $ref: "#/definitions/Error" - headers: - Content-Type: - type: string - Unauthorized: - description: The request could not be authorized - schema: - $ref: "#/definitions/Error" - headers: - Content-Type: - type: string - WWW-Authenticate: - type: string - description: Information about required authentication to access server - InternalServerError: - description: There was an internal error in the server while processing the request - schema: - $ref: "#/definitions/Error" - headers: - Content-Type: - type: string diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go new file mode 100644 index 000000000..e3f643b99 --- /dev/null +++ b/pkg/api/api_test.go @@ -0,0 +1,190 @@ +// +// Copyright 2021 The Sigstore Authors. +// +// 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 api + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "testing" + "time" + + "github.com/sigstore/fulcio/pkg/ca/ephemeralca" + "github.com/sigstore/fulcio/pkg/config" + "gopkg.in/square/go-jose.v2" + "gopkg.in/square/go-jose.v2/jwt" +) + +func TestAPI(t *testing.T) { + signer, issuer := newOIDCIssuer(t) + + subject := strings.ReplaceAll(issuer+"/foo/bar", "http", "spiffe") + + // Create an OIDC token using this issuer's signer. + tok, err := jwt.Signed(signer).Claims(jwt.Claims{ + Issuer: issuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + Expiry: jwt.NewNumericDate(time.Now().Add(30 * time.Minute)), + Subject: subject, + Audience: jwt.Audience{"sigstore"}, + }).CompactSerialize() + if err != nil { + t.Fatalf("CompactSerialize() = %v", err) + } + + // Create a FulcioConfig that supports this issuer. + cfg, err := config.Read([]byte(fmt.Sprintf(`{ + "OIDCIssuers": { + %q: { + "IssuerURL": %q, + "ClientID": "sigstore", + "Type": "spiffe" + } + } + }`, issuer, issuer))) + if err != nil { + t.Fatalf("config.Read() = %v", err) + } + + // Stand up an ephemeral CA we can use for signing certificate requests. + eca, err := ephemeralca.NewEphemeralCA() + if err != nil { + t.Fatalf("ephemeralca.NewEphemeralCA() = %v", err) + } + + // Create a test HTTP server to host our API. + h := NewHandler() + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + ctx := r.Context() + // For each request, infuse context with our snapshot of the FulcioConfig. + ctx = config.With(ctx, cfg) + + // Decorate the context with our CA for testing. + ctx = WithCA(ctx, eca) + + h.ServeHTTP(rw, r.WithContext(ctx)) + })) + t.Cleanup(server.Close) + + // Create an API client that speaks to the API endpoint we created above. + u, err := url.Parse(server.URL) + if err != nil { + t.Fatalf("url.Parse() = %v", err) + } + client := NewClient(u) + + // Sign the subject with our keypair, and provide the public key + // for verification. + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatalf("GenerateKey() = %v", err) + } + pubBytes, err := x509.MarshalPKIXPublicKey(&priv.PublicKey) + if err != nil { + t.Fatalf("x509.MarshalPKIXPublicKey() = %v", err) + } + hash := sha256.Sum256([]byte(subject)) + proof, err := ecdsa.SignASN1(rand.Reader, priv, hash[:]) + if err != nil { + t.Fatalf("SignASN1() = %v", err) + } + + // Hit the API to have it sign our certificate. + resp, err := client.SigningCert(CertificateRequest{ + PublicKey: Key{ + Content: pubBytes, + }, + SignedEmailAddress: proof, + }, tok) + if err != nil { + t.Fatalf("SigningCert() = %v", err) + } + + // We shouldn't have an SCT because we didn't decorate context + // with a ct-log-url + if string(resp.SCT) != "" { + t.Errorf("Unexpected SCT: %s", resp.SCT) + } + + // TODO(mattmoor): What interesting checks can we perform on + // the other return values? +} + +// Stand up a very simple OIDC endpoint. +func newOIDCIssuer(t *testing.T) (jose.Signer, string) { + t.Helper() + + pk, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("Cannot generate RSA key %v", err) + } + jwk := jose.JSONWebKey{ + Algorithm: string(jose.RS256), + Key: pk, + } + signer, err := jose.NewSigner(jose.SigningKey{ + Algorithm: jose.RS256, + Key: jwk.Key, + }, nil) + if err != nil { + t.Fatalf("jose.NewSigner() = %v", err) + } + + // Populated below, but we need to capture it first. + var testIssuer *string + + oidcMux := http.NewServeMux() + + oidcMux.HandleFunc("/.well-known/openid-configuration", func(w http.ResponseWriter, r *http.Request) { + t.Log("Handling request for openid-configuration.") + if err := json.NewEncoder(w).Encode(struct { + Issuer string `json:"issuer"` + JWKSURI string `json:"jwks_uri"` + }{ + Issuer: *testIssuer, + JWKSURI: *testIssuer + "/keys", + }); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + }) + + oidcMux.HandleFunc("/keys", func(w http.ResponseWriter, r *http.Request) { + t.Log("Handling request for jwks.") + if err := json.NewEncoder(w).Encode(jose.JSONWebKeySet{ + Keys: []jose.JSONWebKey{ + jwk.Public(), + }, + }); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + }) + oidcServer := httptest.NewServer(oidcMux) + t.Cleanup(oidcServer.Close) + + // Setup the testIssuer, so everything uses the right URL. + testIssuer = &oidcServer.URL + + return signer, *testIssuer +} diff --git a/pkg/api/ca.go b/pkg/api/ca.go index 26211e15a..8ed121905 100644 --- a/pkg/api/ca.go +++ b/pkg/api/ca.go @@ -19,33 +19,111 @@ import ( "context" "crypto" "crypto/x509" + "encoding/base64" "encoding/json" - "errors" "fmt" "net/http" "strings" "github.com/coreos/go-oidc/v3/oidc" - "github.com/go-openapi/runtime/middleware" certauth "github.com/sigstore/fulcio/pkg/ca" "github.com/sigstore/fulcio/pkg/challenges" "github.com/sigstore/fulcio/pkg/config" "github.com/sigstore/fulcio/pkg/ctl" - "github.com/sigstore/fulcio/pkg/generated/restapi/operations" "github.com/sigstore/fulcio/pkg/log" "github.com/sigstore/sigstore/pkg/cryptoutils" ) -func SigningCertHandler(params operations.SigningCertParams, principal *oidc.IDToken) middleware.Responder { - ctx := params.HTTPRequest.Context() +type Key struct { + // +required + Content []byte `json:"content"` + Algorithm string `json:"algorithm,omitempty"` +} + +type CertificateRequest struct { + // +required + PublicKey Key `json:"publicKey"` + + // +required + SignedEmailAddress []byte `json:"signedEmailAddress"` +} + +const signingCertPath = "/api/v1/signingCert" + +// NewHandler creates a new http.Handler for serving the Fulcio API. +func NewHandler() http.Handler { + handler := http.NewServeMux() + handler.HandleFunc(signingCertPath, signingCert) + return handler +} + +func extractIssuer(token string) (string, error) { + parts := strings.Split(token, ".") + if len(parts) < 2 { + return "", fmt.Errorf("oidc: malformed jwt, expected 3 parts got %d", len(parts)) + } + raw, err := base64.RawURLEncoding.DecodeString(parts[1]) + if err != nil { + return "", fmt.Errorf("oidc: malformed jwt payload: %w", err) + } + var payload struct { + Issuer string `json:"iss"` + } + + if err := json.Unmarshal(raw, &payload); err != nil { + return "", fmt.Errorf("oidc: failed to unmarshal claims: %w", err) + } + return payload.Issuer, nil +} + +// We do this to bypass needing actual OIDC tokens for unit testing. +var authorize = actualAuthorize + +func actualAuthorize(req *http.Request) (*oidc.IDToken, error) { + // Strip off the "Bearer" prefix. + token := strings.Replace(req.Header.Get("Authorization"), "Bearer ", "", 1) + + issuer, err := extractIssuer(token) + if err != nil { + return nil, err + } + + verifier, ok := config.FromContext(req.Context()).GetVerifier(issuer) + if !ok { + return nil, fmt.Errorf("unsupported issuer: %s", issuer) + } + return verifier.Verify(req.Context(), token) +} + +func signingCert(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodPost { + err := fmt.Errorf("signing cert handler must receive POSTs, got %s", req.Method) + handleFulcioAPIError(w, req, http.StatusMethodNotAllowed, err, err.Error()) + return + } + if gotContentType, wantContentType := req.Header.Get("Content-Type"), "application/json"; gotContentType != wantContentType { + err := fmt.Errorf("signing cert handler must receive %q, got %q", wantContentType, gotContentType) + handleFulcioAPIError(w, req, http.StatusBadRequest, err, err.Error()) + return + } + + ctx := req.Context() logger := log.ContextLogger(ctx) - // none of the following cases should happen if the authentication path is working correctly; checking to be defensive - if principal == nil { - return handleFulcioAPIError(params, http.StatusInternalServerError, errors.New("no principal supplied to request"), invalidCredentials) + principal, err := authorize(req) + if err != nil { + handleFulcioAPIError(w, req, http.StatusUnauthorized, err, invalidCredentials) + return + } + + // Parse the request body. + cr := CertificateRequest{} + if err := json.NewDecoder(req.Body).Decode(&cr); err != nil { + handleFulcioAPIError(w, req, http.StatusBadRequest, err, invalidCertificateRequest) + return } - publicKeyBytes := *params.CertificateRequest.PublicKey.Content + publicKeyBytes := cr.PublicKey.Content // try to unmarshal as DER publicKey, err := x509.ParsePKIXPublicKey(publicKeyBytes) if err != nil { @@ -53,13 +131,15 @@ func SigningCertHandler(params operations.SigningCertParams, principal *oidc.IDT logger.Debugf("error parsing public key as DER, trying pem: %v", err.Error()) publicKey, err = cryptoutils.UnmarshalPEMToPublicKey(publicKeyBytes) if err != nil { - return handleFulcioAPIError(params, http.StatusBadRequest, err, invalidPublicKey) + handleFulcioAPIError(w, req, http.StatusBadRequest, err, invalidPublicKey) + return } } - subject, err := ExtractSubject(ctx, principal, publicKey, *params.CertificateRequest.SignedEmailAddress) + subject, err := ExtractSubject(ctx, principal, publicKey, cr.SignedEmailAddress) if err != nil { - return handleFulcioAPIError(params, http.StatusBadRequest, err, invalidSignature) + handleFulcioAPIError(w, req, http.StatusBadRequest, err, invalidSignature) + return } ca := GetCA(ctx) @@ -73,10 +153,12 @@ func SigningCertHandler(params operations.SigningCertParams, principal *oidc.IDT if err != nil { // if the error was due to invalid input in the request, return HTTP 400 if _, ok := err.(certauth.ValidationError); ok { - return handleFulcioAPIError(params, http.StatusBadRequest, err, err.Error()) + handleFulcioAPIError(w, req, http.StatusBadRequest, err, err.Error()) + return } // otherwise return a 500 error to reflect that it is a transient server issue that the client can't resolve - return handleFulcioAPIError(params, http.StatusInternalServerError, err, genericCAError) + handleFulcioAPIError(w, req, http.StatusInternalServerError, err, genericCAError) + return } // TODO: initialize CTL client once @@ -87,11 +169,13 @@ func SigningCertHandler(params operations.SigningCertParams, principal *oidc.IDT c := ctl.New(ctURL) sct, err := c.AddChain(csc) if err != nil { - return handleFulcioAPIError(params, http.StatusInternalServerError, err, fmt.Sprintf(failedToEnterCertInCTL, ctURL)) + handleFulcioAPIError(w, req, http.StatusInternalServerError, err, fmt.Sprintf(failedToEnterCertInCTL, ctURL)) + return } sctBytes, err = json.Marshal(sct) if err != nil { - return handleFulcioAPIError(params, http.StatusInternalServerError, err, failedToMarshalSCT) + handleFulcioAPIError(w, req, http.StatusInternalServerError, err, failedToMarshalSCT) + return } logger.Info("CTL Submission Signature Received: ", sct.Signature) logger.Info("CTL Submission ID Received: ", sct.ID) @@ -105,18 +189,27 @@ func SigningCertHandler(params operations.SigningCertParams, principal *oidc.IDT var ret strings.Builder finalPEM, err := csc.CertPEM() if err != nil { - return handleFulcioAPIError(params, http.StatusInternalServerError, err, failedToMarshalCert) + handleFulcioAPIError(w, req, http.StatusInternalServerError, err, failedToMarshalCert) + return } fmt.Fprintf(&ret, "%s\n", finalPEM) finalChainPEM, err := csc.ChainPEM() if err != nil { - return handleFulcioAPIError(params, http.StatusInternalServerError, err, failedToMarshalCert) + handleFulcioAPIError(w, req, http.StatusInternalServerError, err, failedToMarshalCert) + return } if len(finalChainPEM) > 0 { fmt.Fprintf(&ret, "%s\n", finalChainPEM) } - return operations.NewSigningCertCreated().WithPayload(strings.TrimSpace(ret.String())).WithSCT(sctBytes) + // Set the SCT and Content-Type headers, and then respond with a 201 Created. + w.Header().Add("SCT", string(sctBytes)) + w.Header().Add("Content-Type", "application/pem-certificate-chain") + w.WriteHeader(http.StatusCreated) + // Write the PEM encoded certificate chain to the response body. + if _, err := w.Write([]byte(strings.TrimSpace(ret.String()))); err != nil { + logger.Error("Error writing response: ", err) + } } func ExtractSubject(ctx context.Context, tok *oidc.IDToken, publicKey crypto.PublicKey, challenge []byte) (*challenges.ChallengeResult, error) { diff --git a/pkg/api/client.go b/pkg/api/client.go new file mode 100644 index 000000000..7f3225dc0 --- /dev/null +++ b/pkg/api/client.go @@ -0,0 +1,167 @@ +// +// Copyright 2021 The Sigstore Authors. +// +// 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 api + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "encoding/pem" + "errors" + "io" + "net/http" + "net/url" + "path" +) + +type CertificateResponse struct { + CertPEM []byte + ChainPEM []byte + SCT []byte +} + +// SigstorePublicServerURL is the URL of Sigstore's public Fulcio service. +const SigstorePublicServerURL = "https://fulcio.sigstore.dev" + +// Client is the interface for accessing the Fulcio API. +type Client interface { + // SigningCert sends the provided CertificateRequest to the /api/v1/singingCert + // endpoint of a Fulcio API, authenticated with the provided bearer token. + SigningCert(cr CertificateRequest, token string) (*CertificateResponse, error) +} + +// ClientOption is a functional option for customizing static signatures. +type ClientOption func(*clientOptions) + +// NewClient creates a new Fulcio API client talking to the provided URL. +func NewClient(url *url.URL, opts ...ClientOption) Client { + o := makeOptions(opts...) + + return &client{ + baseURL: url, + client: &http.Client{ + Transport: createRoundTripper(http.DefaultTransport, o), + }, + } +} + +type client struct { + baseURL *url.URL + client *http.Client +} + +var _ Client = (*client)(nil) + +// SigningCert implements Client +func (c *client) SigningCert(cr CertificateRequest, token string) (*CertificateResponse, error) { + // Construct the API endpoint for this handler + endpoint := *c.baseURL + endpoint.Path = path.Join(endpoint.Path, signingCertPath) + + b, err := json.Marshal(cr) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, endpoint.String(), bytes.NewBuffer(b)) + if err != nil { + return nil, err + } + // Set the authorization header to our OIDC bearer token. + req.Header.Set("Authorization", "Bearer "+token) + // Set the content-type to reflect we're sending JSON. + req.Header.Set("Content-Type", "application/json") + + resp, err := c.client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + // The API should return a 201 Created on success. If we see anything else, + // then turn the response body into an error. + if resp.StatusCode != http.StatusCreated { + return nil, errors.New(string(body)) + } + + // Extract the SCT from the response header. + sct, err := base64.StdEncoding.DecodeString(resp.Header.Get("SCT")) + if err != nil { + return nil, err + } + + // Split the cert and the chain + certBlock, chainPem := pem.Decode(body) + certPem := pem.EncodeToMemory(certBlock) + return &CertificateResponse{ + CertPEM: certPem, + ChainPEM: chainPem, + SCT: sct, + }, nil +} + +type clientOptions struct { + UserAgent string +} + +func makeOptions(opts ...ClientOption) *clientOptions { + o := &clientOptions{ + UserAgent: "", + } + + for _, opt := range opts { + opt(o) + } + + return o +} + +// WithUserAgent sets the media type of the signature. +func WithUserAgent(userAgent string) ClientOption { + return func(o *clientOptions) { + o.UserAgent = userAgent + } +} + +type roundTripper struct { + http.RoundTripper + UserAgent string +} + +// RoundTrip implements `http.RoundTripper` +func (rt *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Set("User-Agent", rt.UserAgent) + return rt.RoundTripper.RoundTrip(req) +} + +func createRoundTripper(inner http.RoundTripper, o *clientOptions) http.RoundTripper { + if inner == nil { + inner = http.DefaultTransport + } + if o.UserAgent == "" { + // There's nothing to do... + return inner + } + return &roundTripper{ + RoundTripper: inner, + UserAgent: o.UserAgent, + } +} diff --git a/pkg/api/error.go b/pkg/api/error.go index ff6d475e3..2ae608de4 100644 --- a/pkg/api/error.go +++ b/pkg/api/error.go @@ -18,62 +18,27 @@ package api import ( "fmt" "net/http" - "regexp" - "github.com/go-openapi/runtime/middleware" - "github.com/mitchellh/mapstructure" - - "github.com/sigstore/fulcio/pkg/generated/models" - "github.com/sigstore/fulcio/pkg/generated/restapi/operations" "github.com/sigstore/fulcio/pkg/log" ) const ( - invalidSignature = "The signature supplied in the request could not be verified" - invalidPublicKey = "The public key supplied in the request could not be parsed" - failedToEnterCertInCTL = "Error entering certificate in CTL @ '%v'" - failedToMarshalSCT = "Error marshaling signed certificate timestamp" - failedToMarshalCert = "Error marshaling code signing certificate" + invalidSignature = "The signature supplied in the request could not be verified" + invalidCertificateRequest = "The CertificateRequest was invalid" + invalidPublicKey = "The public key supplied in the request could not be parsed" + failedToEnterCertInCTL = "Error entering certificate in CTL @ '%v'" + failedToMarshalSCT = "Error marshaling signed certificate timestamp" + failedToMarshalCert = "Error marshaling code signing certificate" //nolint invalidCredentials = "There was an error processing the credentials for this request" genericCAError = "error communicating with CA backend" ) -func errorMsg(message string, code int) *models.Error { - return &models.Error{ - Code: int64(code), - Message: message, - } -} - -func handleFulcioAPIError(params interface{}, code int, err error, message string, fields ...interface{}) middleware.Responder { +func handleFulcioAPIError(w http.ResponseWriter, req *http.Request, code int, err error, message string, fields ...interface{}) { if message == "" { message = http.StatusText(code) } - re := regexp.MustCompile("^(.*)Params$") - typeStr := fmt.Sprintf("%T", params) - handler := re.FindStringSubmatch(typeStr)[1] - - logMsg := func(r *http.Request) { - log.RequestIDLogger(r).Errorw("exiting with error", append([]interface{}{"handler", handler, "statusCode", code, "clientMessage", message, "error", err}, fields...)...) - paramsFields := map[string]interface{}{} - if err := mapstructure.Decode(params, ¶msFields); err == nil { - log.RequestIDLogger(r).Debug(paramsFields) - } - } - - switch params := params.(type) { - case operations.SigningCertParams: - logMsg(params.HTTPRequest) - switch code { - case http.StatusBadRequest: - return operations.NewSigningCertBadRequest().WithPayload(errorMsg(message, code)).WithContentType("application/json") - default: - return operations.NewSigningCertDefault(code).WithPayload(errorMsg(message, code)).WithContentType("application/json") - } - default: - log.Logger.Errorf("unable to find method for type %T; error: %v", params, err) - return middleware.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) - } + log.RequestIDLogger(req).Errorw("exiting with error", append([]interface{}{"handler", req.URL.Path, "statusCode", code, "clientMessage", message, "error", err}, fields...)...) + http.Error(w, fmt.Sprintf(`{"code":%d,"message":%q}`, code, message), code) } diff --git a/pkg/client/client_test.go b/pkg/api/options_test.go similarity index 88% rename from pkg/client/client_test.go rename to pkg/api/options_test.go index 264b26a03..5f244a63c 100644 --- a/pkg/client/client_test.go +++ b/pkg/api/options_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package client +package api import ( "net/http" @@ -26,15 +26,15 @@ func TestMakeOptions(t *testing.T) { tests := []struct { desc string - opts []Option - want *options + opts []ClientOption + want *clientOptions }{{ desc: "no opts", - want: &options{}, + want: &clientOptions{}, }, { desc: "WithUserAgent", - opts: []Option{WithUserAgent("test user agent")}, - want: &options{UserAgent: "test user agent"}, + opts: []ClientOption{WithUserAgent("test user agent")}, + want: &clientOptions{UserAgent: "test user agent"}, }} for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { @@ -61,7 +61,7 @@ func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) func TestCreateRoundTripper(t *testing.T) { t.Run("always returns non-nil", func(t *testing.T) { - got := createRoundTripper(nil, &options{}) + got := createRoundTripper(nil, &clientOptions{}) if got == nil { t.Errorf("createRoundTripper() should never return a nil `http.RoundTripper`") } @@ -81,7 +81,7 @@ func TestCreateRoundTripper(t *testing.T) { expectedUserAgent := "test UserAgent" m := &mockRoundTripper{} - rt := createRoundTripper(m, &options{ + rt := createRoundTripper(m, &clientOptions{ UserAgent: expectedUserAgent, }) m.resp = testResp @@ -110,7 +110,7 @@ func TestSanity(t *testing.T) { t.Fatalf("url.Parse(SigstorePublicServerURL) returned error: %v", err) } - got := New(testURL, WithUserAgent("sanity test")) + got := NewClient(testURL, WithUserAgent("sanity test")) if got == nil { t.Fatalf(`New(testURL, WithUserAgent("sanity test")) returned nil`) } diff --git a/pkg/challenges/challenges.go b/pkg/challenges/challenges.go index 575858be6..d3ad05bf1 100644 --- a/pkg/challenges/challenges.go +++ b/pkg/challenges/challenges.go @@ -270,14 +270,15 @@ func workflowInfoFromIDToken(token *oidc.IDToken) (map[AdditionalInfo]string, er } func isSpiffeIDAllowed(host, spiffeID string) bool { - // Strip spiffe:// - name := strings.TrimPrefix(spiffeID, "spiffe://") - - // get the host part - spiffeDomain := strings.Split(name, "/")[0] - - if spiffeDomain == host { + u, err := url.Parse(spiffeID) + if err != nil { + return false + } + if u.Scheme != "spiffe" { + return false + } + if u.Hostname() == host { return true } - return strings.Contains(spiffeDomain, "."+host) + return strings.Contains(u.Hostname(), "."+host) } diff --git a/pkg/client/client.go b/pkg/client/client.go deleted file mode 100644 index 932c0a15a..000000000 --- a/pkg/client/client.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2021 The Sigstore Authors. -// -// 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 client - -import ( - "net/http" - "net/url" - - "github.com/go-openapi/runtime" - httptransport "github.com/go-openapi/runtime/client" - "github.com/go-openapi/strfmt" - - genclient "github.com/sigstore/fulcio/pkg/generated/client" -) - -// SigstorePublicServerURL is the URL of Sigstore's public Fulcio service. -const SigstorePublicServerURL = "https://fulcio.sigstore.dev" - -// Option is a functional option for customizing static signatures. -type Option func(*options) - -type options struct { - UserAgent string -} - -func makeOptions(opts ...Option) *options { - o := &options{ - UserAgent: "", - } - - for _, opt := range opts { - opt(o) - } - - return o -} - -// WithUserAgent sets the media type of the signature. -func WithUserAgent(userAgent string) Option { - return func(o *options) { - o.UserAgent = userAgent - } -} - -type roundTripper struct { - http.RoundTripper - UserAgent string -} - -// RoundTrip implements `http.RoundTripper` -func (rt *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - req.Header.Set("User-Agent", rt.UserAgent) - return rt.RoundTripper.RoundTrip(req) -} - -func createRoundTripper(inner http.RoundTripper, o *options) http.RoundTripper { - if inner == nil { - inner = http.DefaultTransport - } - if o.UserAgent == "" { - // There's nothing to do... - return inner - } - return &roundTripper{ - RoundTripper: inner, - UserAgent: o.UserAgent, - } -} - -// New returns a new client to interact with the given fulcio server. -func New(server *url.URL, opts ...Option) *genclient.Fulcio { - o := makeOptions(opts...) - rt := httptransport.New(server.Host, genclient.DefaultBasePath, []string{server.Scheme}) - rt.Consumers["application/pem-certificate-chain"] = runtime.TextConsumer() - rt.Transport = createRoundTripper(rt.Transport, o) - return genclient.New(rt, strfmt.Default) -} diff --git a/pkg/config/config.go b/pkg/config/config.go index d1ccb1258..937fee6c3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -132,6 +132,24 @@ func (fc *FulcioConfig) GetVerifier(issuerURL string) (*oidc.IDTokenVerifier, bo return verifier, true } +func (fc *FulcioConfig) prepare() error { + fc.verifiers = make(map[string]*oidc.IDTokenVerifier, len(fc.OIDCIssuers)) + for _, iss := range fc.OIDCIssuers { + provider, err := oidc.NewProvider(context.Background(), iss.IssuerURL) + if err != nil { + return err + } + fc.verifiers[iss.IssuerURL] = provider.Verifier(&oidc.Config{ClientID: iss.ClientID}) + } + + cache, err := lru.New2Q(100 /* size */) + if err != nil { + return err + } + fc.lru = cache + return nil +} + type IssuerType string const ( @@ -189,27 +207,29 @@ func FromContext(ctx context.Context) *FulcioConfig { // Load a config from disk, or use defaults func Load(configPath string) (*FulcioConfig, error) { - var config *FulcioConfig if _, err := os.Stat(configPath); os.IsNotExist(err) { log.Logger.Infof("No config at %s, using defaults: %v", configPath, DefaultConfig) - config = DefaultConfig - cache, err := lru.New2Q(100 /* size */) - if err != nil { + config := DefaultConfig + if err := config.prepare(); err != nil { return nil, err } - config.lru = cache return config, nil } b, err := ioutil.ReadFile(configPath) if err != nil { return nil, err } - cfg, err := parseConfig(b) + return Read(b) +} + +// Read parses the bytes of a config +func Read(b []byte) (*FulcioConfig, error) { + config, err := parseConfig(b) if err != nil { return nil, err } - if _, ok := cfg.GetIssuer("https://kubernetes.default.svc"); ok { + if _, ok := config.GetIssuer("https://kubernetes.default.svc"); ok { // Add the Kubernetes cluster's CA to the system CA pool, and to // the default transport. rootCAs, _ := x509.SystemCertPool() @@ -235,24 +255,8 @@ func Load(configPath string) (*FulcioConfig, error) { http.DefaultTransport = originalTransport } - // Eagerly populate the verifiers for the OIDCIssuers. - cfg.verifiers = make(map[string]*oidc.IDTokenVerifier, len(cfg.OIDCIssuers)) - for _, iss := range cfg.OIDCIssuers { - provider, err := oidc.NewProvider(context.Background(), iss.IssuerURL) - if err != nil { - return nil, err - } - verifier := provider.Verifier(&oidc.Config{ClientID: iss.ClientID}) - cfg.verifiers[iss.IssuerURL] = verifier - } - - cache, err := lru.New2Q(100 /* size */) - if err != nil { + if err := config.prepare(); err != nil { return nil, err } - cfg.lru = cache - - config = cfg - log.Logger.Infof("Loaded config %v from %s", cfg, configPath) return config, nil } diff --git a/pkg/generated/client/fulcio_client.go b/pkg/generated/client/fulcio_client.go deleted file mode 100644 index 5a2afe209..000000000 --- a/pkg/generated/client/fulcio_client.go +++ /dev/null @@ -1,127 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 client - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "github.com/go-openapi/runtime" - httptransport "github.com/go-openapi/runtime/client" - "github.com/go-openapi/strfmt" - "github.com/sigstore/fulcio/pkg/generated/client/operations" -) - -// Default fulcio HTTP client. -var Default = NewHTTPClient(nil) - -const ( - // DefaultHost is the default Host - // found in Meta (info) section of spec file - DefaultHost string = "fulcio.sigstore.dev" - // DefaultBasePath is the default BasePath - // found in Meta (info) section of spec file - DefaultBasePath string = "/api/v1" -) - -// DefaultSchemes are the default schemes found in Meta (info) section of spec file -var DefaultSchemes = []string{"http", "https"} - -// NewHTTPClient creates a new fulcio HTTP client. -func NewHTTPClient(formats strfmt.Registry) *Fulcio { - return NewHTTPClientWithConfig(formats, nil) -} - -// NewHTTPClientWithConfig creates a new fulcio HTTP client, -// using a customizable transport config. -func NewHTTPClientWithConfig(formats strfmt.Registry, cfg *TransportConfig) *Fulcio { - // ensure nullable parameters have default - if cfg == nil { - cfg = DefaultTransportConfig() - } - - // create transport and client - transport := httptransport.New(cfg.Host, cfg.BasePath, cfg.Schemes) - return New(transport, formats) -} - -// New creates a new fulcio client -func New(transport runtime.ClientTransport, formats strfmt.Registry) *Fulcio { - // ensure nullable parameters have default - if formats == nil { - formats = strfmt.Default - } - - cli := new(Fulcio) - cli.Transport = transport - cli.Operations = operations.New(transport, formats) - return cli -} - -// DefaultTransportConfig creates a TransportConfig with the -// default settings taken from the meta section of the spec file. -func DefaultTransportConfig() *TransportConfig { - return &TransportConfig{ - Host: DefaultHost, - BasePath: DefaultBasePath, - Schemes: DefaultSchemes, - } -} - -// TransportConfig contains the transport related info, -// found in the meta section of the spec file. -type TransportConfig struct { - Host string - BasePath string - Schemes []string -} - -// WithHost overrides the default host, -// provided by the meta section of the spec file. -func (cfg *TransportConfig) WithHost(host string) *TransportConfig { - cfg.Host = host - return cfg -} - -// WithBasePath overrides the default basePath, -// provided by the meta section of the spec file. -func (cfg *TransportConfig) WithBasePath(basePath string) *TransportConfig { - cfg.BasePath = basePath - return cfg -} - -// WithSchemes overrides the default schemes, -// provided by the meta section of the spec file. -func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig { - cfg.Schemes = schemes - return cfg -} - -// Fulcio is a client for fulcio -type Fulcio struct { - Operations operations.ClientService - - Transport runtime.ClientTransport -} - -// SetTransport changes the transport on the client and all its subresources -func (c *Fulcio) SetTransport(transport runtime.ClientTransport) { - c.Transport = transport - c.Operations.SetTransport(transport) -} diff --git a/pkg/generated/client/operations/operations_client.go b/pkg/generated/client/operations/operations_client.go deleted file mode 100644 index 56a2326fb..000000000 --- a/pkg/generated/client/operations/operations_client.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" -) - -// New creates a new operations API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { - return &Client{transport: transport, formats: formats} -} - -/* -Client for operations API -*/ -type Client struct { - transport runtime.ClientTransport - formats strfmt.Registry -} - -// ClientOption is the option for Client methods -type ClientOption func(*runtime.ClientOperation) - -// ClientService is the interface for Client methods -type ClientService interface { - SigningCert(params *SigningCertParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*SigningCertCreated, error) - - SetTransport(transport runtime.ClientTransport) -} - -/* - SigningCert create a cert, return content with a location header (with URL to CTL entry) -*/ -func (a *Client) SigningCert(params *SigningCertParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*SigningCertCreated, error) { - // TODO: Validate the params before sending - if params == nil { - params = NewSigningCertParams() - } - op := &runtime.ClientOperation{ - ID: "signingCert", - Method: "POST", - PathPattern: "/signingCert", - ProducesMediaTypes: []string{"application/pem-certificate-chain"}, - ConsumesMediaTypes: []string{"application/json"}, - Schemes: []string{"http", "https"}, - Params: params, - Reader: &SigningCertReader{formats: a.formats}, - AuthInfo: authInfo, - Context: params.Context, - Client: params.HTTPClient, - } - for _, opt := range opts { - opt(op) - } - - result, err := a.transport.Submit(op) - if err != nil { - return nil, err - } - success, ok := result.(*SigningCertCreated) - if ok { - return success, nil - } - // unexpected success response - unexpectedSuccess := result.(*SigningCertDefault) - return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) -} - -// SetTransport changes the transport on the client -func (a *Client) SetTransport(transport runtime.ClientTransport) { - a.transport = transport -} diff --git a/pkg/generated/client/operations/signing_cert_parameters.go b/pkg/generated/client/operations/signing_cert_parameters.go deleted file mode 100644 index e31a73ee3..000000000 --- a/pkg/generated/client/operations/signing_cert_parameters.go +++ /dev/null @@ -1,167 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "context" - "net/http" - "time" - - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - cr "github.com/go-openapi/runtime/client" - "github.com/go-openapi/strfmt" - - "github.com/sigstore/fulcio/pkg/generated/models" -) - -// NewSigningCertParams creates a new SigningCertParams object, -// with the default timeout for this client. -// -// Default values are not hydrated, since defaults are normally applied by the API server side. -// -// To enforce default values in parameter, use SetDefaults or WithDefaults. -func NewSigningCertParams() *SigningCertParams { - return &SigningCertParams{ - timeout: cr.DefaultTimeout, - } -} - -// NewSigningCertParamsWithTimeout creates a new SigningCertParams object -// with the ability to set a timeout on a request. -func NewSigningCertParamsWithTimeout(timeout time.Duration) *SigningCertParams { - return &SigningCertParams{ - timeout: timeout, - } -} - -// NewSigningCertParamsWithContext creates a new SigningCertParams object -// with the ability to set a context for a request. -func NewSigningCertParamsWithContext(ctx context.Context) *SigningCertParams { - return &SigningCertParams{ - Context: ctx, - } -} - -// NewSigningCertParamsWithHTTPClient creates a new SigningCertParams object -// with the ability to set a custom HTTPClient for a request. -func NewSigningCertParamsWithHTTPClient(client *http.Client) *SigningCertParams { - return &SigningCertParams{ - HTTPClient: client, - } -} - -/* SigningCertParams contains all the parameters to send to the API endpoint - for the signing cert operation. - - Typically these are written to a http.Request. -*/ -type SigningCertParams struct { - - /* CertificateRequest. - - Request for signing certificate - */ - CertificateRequest *models.CertificateRequest - - timeout time.Duration - Context context.Context - HTTPClient *http.Client -} - -// WithDefaults hydrates default values in the signing cert params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *SigningCertParams) WithDefaults() *SigningCertParams { - o.SetDefaults() - return o -} - -// SetDefaults hydrates default values in the signing cert params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *SigningCertParams) SetDefaults() { - // no default values defined for this parameter -} - -// WithTimeout adds the timeout to the signing cert params -func (o *SigningCertParams) WithTimeout(timeout time.Duration) *SigningCertParams { - o.SetTimeout(timeout) - return o -} - -// SetTimeout adds the timeout to the signing cert params -func (o *SigningCertParams) SetTimeout(timeout time.Duration) { - o.timeout = timeout -} - -// WithContext adds the context to the signing cert params -func (o *SigningCertParams) WithContext(ctx context.Context) *SigningCertParams { - o.SetContext(ctx) - return o -} - -// SetContext adds the context to the signing cert params -func (o *SigningCertParams) SetContext(ctx context.Context) { - o.Context = ctx -} - -// WithHTTPClient adds the HTTPClient to the signing cert params -func (o *SigningCertParams) WithHTTPClient(client *http.Client) *SigningCertParams { - o.SetHTTPClient(client) - return o -} - -// SetHTTPClient adds the HTTPClient to the signing cert params -func (o *SigningCertParams) SetHTTPClient(client *http.Client) { - o.HTTPClient = client -} - -// WithCertificateRequest adds the certificateRequest to the signing cert params -func (o *SigningCertParams) WithCertificateRequest(certificateRequest *models.CertificateRequest) *SigningCertParams { - o.SetCertificateRequest(certificateRequest) - return o -} - -// SetCertificateRequest adds the certificateRequest to the signing cert params -func (o *SigningCertParams) SetCertificateRequest(certificateRequest *models.CertificateRequest) { - o.CertificateRequest = certificateRequest -} - -// WriteToRequest writes these params to a swagger request -func (o *SigningCertParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { - - if err := r.SetTimeout(o.timeout); err != nil { - return err - } - var res []error - if o.CertificateRequest != nil { - if err := r.SetBodyParam(o.CertificateRequest); err != nil { - return err - } - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} diff --git a/pkg/generated/client/operations/signing_cert_responses.go b/pkg/generated/client/operations/signing_cert_responses.go deleted file mode 100644 index 5913bdc04..000000000 --- a/pkg/generated/client/operations/signing_cert_responses.go +++ /dev/null @@ -1,261 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "fmt" - "io" - - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" - - "github.com/sigstore/fulcio/pkg/generated/models" -) - -// SigningCertReader is a Reader for the SigningCert structure. -type SigningCertReader struct { - formats strfmt.Registry -} - -// ReadResponse reads a server response into the received o. -func (o *SigningCertReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { - switch response.Code() { - case 201: - result := NewSigningCertCreated() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return result, nil - case 400: - result := NewSigningCertBadRequest() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return nil, result - case 401: - result := NewSigningCertUnauthorized() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return nil, result - default: - result := NewSigningCertDefault(response.Code()) - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - if response.Code()/100 == 2 { - return result, nil - } - return nil, result - } -} - -// NewSigningCertCreated creates a SigningCertCreated with default headers values -func NewSigningCertCreated() *SigningCertCreated { - return &SigningCertCreated{} -} - -/* SigningCertCreated describes a response with status code 201, with default header values. - -Generated Certificate Chain -*/ -type SigningCertCreated struct { - - /* Signed Certificate Timestamp from Entry in CT Log - - Format: byte - */ - SCT strfmt.Base64 - - Payload string -} - -func (o *SigningCertCreated) Error() string { - return fmt.Sprintf("[POST /signingCert][%d] signingCertCreated %+v", 201, o.Payload) -} -func (o *SigningCertCreated) GetPayload() string { - return o.Payload -} - -func (o *SigningCertCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - // hydrates response header SCT - hdrSCT := response.GetHeader("SCT") - - if hdrSCT != "" { - valsCT, err := formats.Parse("byte", hdrSCT) - if err != nil { - return errors.InvalidType("SCT", "header", "strfmt.Base64", hdrSCT) - } - o.SCT = *(valsCT.(*strfmt.Base64)) - } - - // response payload - if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { - return err - } - - return nil -} - -// NewSigningCertBadRequest creates a SigningCertBadRequest with default headers values -func NewSigningCertBadRequest() *SigningCertBadRequest { - return &SigningCertBadRequest{} -} - -/* SigningCertBadRequest describes a response with status code 400, with default header values. - -The content supplied to the server was invalid -*/ -type SigningCertBadRequest struct { - ContentType string - - Payload *models.Error -} - -func (o *SigningCertBadRequest) Error() string { - return fmt.Sprintf("[POST /signingCert][%d] signingCertBadRequest %+v", 400, o.Payload) -} -func (o *SigningCertBadRequest) GetPayload() *models.Error { - return o.Payload -} - -func (o *SigningCertBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - // hydrates response header Content-Type - hdrContentType := response.GetHeader("Content-Type") - - if hdrContentType != "" { - o.ContentType = hdrContentType - } - - o.Payload = new(models.Error) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { - return err - } - - return nil -} - -// NewSigningCertUnauthorized creates a SigningCertUnauthorized with default headers values -func NewSigningCertUnauthorized() *SigningCertUnauthorized { - return &SigningCertUnauthorized{} -} - -/* SigningCertUnauthorized describes a response with status code 401, with default header values. - -The request could not be authorized -*/ -type SigningCertUnauthorized struct { - ContentType string - - /* Information about required authentication to access server - */ - WWWAuthenticate string - - Payload *models.Error -} - -func (o *SigningCertUnauthorized) Error() string { - return fmt.Sprintf("[POST /signingCert][%d] signingCertUnauthorized %+v", 401, o.Payload) -} -func (o *SigningCertUnauthorized) GetPayload() *models.Error { - return o.Payload -} - -func (o *SigningCertUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - // hydrates response header Content-Type - hdrContentType := response.GetHeader("Content-Type") - - if hdrContentType != "" { - o.ContentType = hdrContentType - } - - // hydrates response header WWW-Authenticate - hdrWWWAuthenticate := response.GetHeader("WWW-Authenticate") - - if hdrWWWAuthenticate != "" { - o.WWWAuthenticate = hdrWWWAuthenticate - } - - o.Payload = new(models.Error) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { - return err - } - - return nil -} - -// NewSigningCertDefault creates a SigningCertDefault with default headers values -func NewSigningCertDefault(code int) *SigningCertDefault { - return &SigningCertDefault{ - _statusCode: code, - } -} - -/* SigningCertDefault describes a response with status code -1, with default header values. - -There was an internal error in the server while processing the request -*/ -type SigningCertDefault struct { - _statusCode int - ContentType string - - Payload *models.Error -} - -// Code gets the status code for the signing cert default response -func (o *SigningCertDefault) Code() int { - return o._statusCode -} - -func (o *SigningCertDefault) Error() string { - return fmt.Sprintf("[POST /signingCert][%d] signingCert default %+v", o._statusCode, o.Payload) -} -func (o *SigningCertDefault) GetPayload() *models.Error { - return o.Payload -} - -func (o *SigningCertDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - // hydrates response header Content-Type - hdrContentType := response.GetHeader("Content-Type") - - if hdrContentType != "" { - o.ContentType = hdrContentType - } - - o.Payload = new(models.Error) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { - return err - } - - return nil -} diff --git a/pkg/generated/models/certificate_request.go b/pkg/generated/models/certificate_request.go deleted file mode 100644 index dc2a5e4ba..000000000 --- a/pkg/generated/models/certificate_request.go +++ /dev/null @@ -1,246 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "context" - "encoding/json" - - "github.com/go-openapi/errors" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// CertificateRequest certificate request -// -// swagger:model CertificateRequest -type CertificateRequest struct { - - // public key - // Required: true - PublicKey *CertificateRequestPublicKey `json:"publicKey"` - - // signed email address - // Required: true - // Format: byte - SignedEmailAddress *strfmt.Base64 `json:"signedEmailAddress"` -} - -// Validate validates this certificate request -func (m *CertificateRequest) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validatePublicKey(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSignedEmailAddress(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *CertificateRequest) validatePublicKey(formats strfmt.Registry) error { - - if err := validate.Required("publicKey", "body", m.PublicKey); err != nil { - return err - } - - if m.PublicKey != nil { - if err := m.PublicKey.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("publicKey") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("publicKey") - } - return err - } - } - - return nil -} - -func (m *CertificateRequest) validateSignedEmailAddress(formats strfmt.Registry) error { - - if err := validate.Required("signedEmailAddress", "body", m.SignedEmailAddress); err != nil { - return err - } - - return nil -} - -// ContextValidate validate this certificate request based on the context it is used -func (m *CertificateRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var res []error - - if err := m.contextValidatePublicKey(ctx, formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *CertificateRequest) contextValidatePublicKey(ctx context.Context, formats strfmt.Registry) error { - - if m.PublicKey != nil { - if err := m.PublicKey.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("publicKey") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("publicKey") - } - return err - } - } - - return nil -} - -// MarshalBinary interface implementation -func (m *CertificateRequest) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *CertificateRequest) UnmarshalBinary(b []byte) error { - var res CertificateRequest - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} - -// CertificateRequestPublicKey certificate request public key -// -// swagger:model CertificateRequestPublicKey -type CertificateRequestPublicKey struct { - - // algorithm - // Enum: [ecdsa] - Algorithm string `json:"algorithm,omitempty"` - - // content - // Required: true - // Format: byte - Content *strfmt.Base64 `json:"content"` -} - -// Validate validates this certificate request public key -func (m *CertificateRequestPublicKey) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateAlgorithm(formats); err != nil { - res = append(res, err) - } - - if err := m.validateContent(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -var certificateRequestPublicKeyTypeAlgorithmPropEnum []interface{} - -func init() { - var res []string - if err := json.Unmarshal([]byte(`["ecdsa"]`), &res); err != nil { - panic(err) - } - for _, v := range res { - certificateRequestPublicKeyTypeAlgorithmPropEnum = append(certificateRequestPublicKeyTypeAlgorithmPropEnum, v) - } -} - -const ( - - // CertificateRequestPublicKeyAlgorithmEcdsa captures enum value "ecdsa" - CertificateRequestPublicKeyAlgorithmEcdsa string = "ecdsa" -) - -// prop value enum -func (m *CertificateRequestPublicKey) validateAlgorithmEnum(path, location string, value string) error { - if err := validate.EnumCase(path, location, value, certificateRequestPublicKeyTypeAlgorithmPropEnum, true); err != nil { - return err - } - return nil -} - -func (m *CertificateRequestPublicKey) validateAlgorithm(formats strfmt.Registry) error { - if swag.IsZero(m.Algorithm) { // not required - return nil - } - - // value enum - if err := m.validateAlgorithmEnum("publicKey"+"."+"algorithm", "body", m.Algorithm); err != nil { - return err - } - - return nil -} - -func (m *CertificateRequestPublicKey) validateContent(formats strfmt.Registry) error { - - if err := validate.Required("publicKey"+"."+"content", "body", m.Content); err != nil { - return err - } - - return nil -} - -// ContextValidate validates this certificate request public key based on context it is used -func (m *CertificateRequestPublicKey) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (m *CertificateRequestPublicKey) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *CertificateRequestPublicKey) UnmarshalBinary(b []byte) error { - var res CertificateRequestPublicKey - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/generated/models/error.go b/pkg/generated/models/error.go deleted file mode 100644 index ac14f2026..000000000 --- a/pkg/generated/models/error.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "context" - - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" -) - -// Error error -// -// swagger:model Error -type Error struct { - - // code - Code int64 `json:"code,omitempty"` - - // message - Message string `json:"message,omitempty"` -} - -// Validate validates this error -func (m *Error) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this error based on context it is used -func (m *Error) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (m *Error) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Error) UnmarshalBinary(b []byte) error { - var res Error - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/generated/restapi/configure_fulcio_server.go b/pkg/generated/restapi/configure_fulcio_server.go deleted file mode 100644 index b6a6801dd..000000000 --- a/pkg/generated/restapi/configure_fulcio_server.go +++ /dev/null @@ -1,251 +0,0 @@ -// This file is safe to edit. Once it exists it will not be overwritten - -// /* -// Copyright The Fulcio Authors. -// -// 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 restapi - -import ( - "context" - "crypto/tls" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "strconv" - "strings" - "time" - - // using embed to add the static html page duing build time - _ "embed" - - "github.com/go-chi/chi/middleware" - goaerrors "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/security" - "github.com/mitchellh/mapstructure" - "github.com/rs/cors" - - pkgapi "github.com/sigstore/fulcio/pkg/api" - "github.com/sigstore/fulcio/pkg/config" - "github.com/sigstore/fulcio/pkg/generated/restapi/operations" - "github.com/sigstore/fulcio/pkg/log" -) - -//go:generate swagger generate server --target ../../generated --name FulcioServer --spec ../../../openapi.yaml --principal interface{} --exclude-main - -func configureFlags(api *operations.FulcioServerAPI) { - // api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ ... } -} - -func extractIssuer(token string) (string, error) { - parts := strings.Split(token, ".") - if len(parts) < 2 { - return "", fmt.Errorf("oidc: malformed jwt, expected 3 parts got %d", len(parts)) - } - raw, err := base64.RawURLEncoding.DecodeString(parts[1]) - if err != nil { - return "", fmt.Errorf("oidc: malformed jwt payload: %w", err) - } - var payload struct { - Issuer string `json:"iss"` - } - - if err := json.Unmarshal(raw, &payload); err != nil { - return "", fmt.Errorf("oidc: failed to unmarshal claims: %w", err) - } - return payload.Issuer, nil -} - -func configureAPI(api *operations.FulcioServerAPI) http.Handler { - // configure the api here - api.ServeError = logAndServeError - - // Set your custom logger if needed. Default one is log.Printf - // Expected interface func(string, ...interface{}) - // - // Example: - api.Logger = log.Logger.Infof - - // api.UseSwaggerUI() - // To continue using redoc as your UI, uncomment the following line - // api.UseRedoc() - - api.JSONConsumer = runtime.JSONConsumer() - api.ApplicationPemCertificateChainProducer = runtime.TextProducer() - - authenticate := func(ctx context.Context, token string) (interface{}, error) { - token = strings.Replace(token, "Bearer ", "", 1) - - issuer, err := extractIssuer(token) - if err != nil { - return nil, goaerrors.New(http.StatusBadRequest, err.Error()) - } - - verifier, ok := config.FromContext(ctx).GetVerifier(issuer) - if !ok { - return nil, goaerrors.New(http.StatusBadRequest, fmt.Sprintf("unsupported issuer: %s", issuer)) - } - - idToken, err := verifier.Verify(ctx, token) - if err != nil { - return nil, goaerrors.New(http.StatusUnauthorized, err.Error()) - } - return idToken, nil - } - - api.APIKeyAuthenticator = func(name, in string, _ security.TokenAuthentication) runtime.Authenticator { - return security.HttpAuthenticator(func(r *http.Request) (bool, interface{}, error) { - var token string - switch strings.ToLower(in) { - case "header": - token = r.Header.Get(name) - case "query": - token = r.URL.Query().Get(name) - default: - return false, nil, goaerrors.New(500, "api key auth: in value needs to be either \"query\" or \"header\".") - } - - if token == "" { - return false, nil, nil - } - - p, err := authenticate(r.Context(), token) - return true, p, err - }) - } - - // Select which CA / KMS system to use - // Currently supported: - // googleca: Google Certficate Authority Service - // fulcio: Generic PKCS11 / HSM backed servic - api.SigningCertHandler = operations.SigningCertHandlerFunc(pkgapi.SigningCertHandler) - - api.PreServerShutdown = func() {} - - api.ServerShutdown = func() {} - - api.AddMiddlewareFor("POST", "/api/v1/signingCert", middleware.NoCache) - - return setupGlobalMiddleware(api.Serve(setupMiddlewares)) -} - -// The TLS configuration before HTTPS server starts. -func configureTLS(tlsConfig *tls.Config) { - // Make all necessary changes to the TLS configuration here. -} - -// As soon as server is initialized but not run yet, this function will be called. -// If you need to modify a config, store server instance to stop it individually later, this is the place. -// This function can be called multiple times, depending on the number of serving schemes. -// scheme value will be set accordingly: "http", "https" or "unix". -func configureServer(s *http.Server, scheme, addr string) { -} - -// The middleware configuration is for the handler executors. These do not apply to the swagger.json document. -// The middleware executes after routing but before authentication, binding and validation. -func setupMiddlewares(handler http.Handler) http.Handler { - return handler -} - -// We need this type to act as an adapter between zap and the middleware request logger. -type logAdapter struct { -} - -func (l *logAdapter) Print(v ...interface{}) { - log.Logger.Info(v...) -} - -// The middleware configuration happens before anything, this middleware also applies to serving the swagger.json document. -// So this is a good place to plug in a panic handling middleware, logging and metrics. -func setupGlobalMiddleware(handler http.Handler) http.Handler { - middleware.DefaultLogger = middleware.RequestLogger( - &middleware.DefaultLogFormatter{Logger: &logAdapter{}}) - returnHandler := middleware.Logger(handler) - returnHandler = middleware.Recoverer(returnHandler) - returnHandler = middleware.Heartbeat("/ping")(returnHandler) - returnHandler = serveStaticContent(returnHandler) - - handleCORS := cors.Default().Handler - returnHandler = handleCORS(returnHandler) - - returnHandler = wrapMetrics(returnHandler) - - return middleware.RequestID(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - r = r.WithContext(log.WithRequestID(ctx, middleware.GetReqID(ctx))) - defer func() { - _ = log.RequestIDLogger(r).Sync() - }() - - returnHandler.ServeHTTP(w, r) - })) -} - -func wrapMetrics(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor) - defer func() { - // This logs latency broken down by URL path and response code - pkgapi.MetricLatency.With(map[string]string{ - "path": r.URL.Path, - "code": strconv.Itoa(ww.Status()), - }).Observe(float64(time.Since(start))) - }() - - handler.ServeHTTP(ww, r) - - }) -} - -func logAndServeError(w http.ResponseWriter, r *http.Request, err error) { - log.RequestIDLogger(r).Error(err) - requestFields := map[string]interface{}{} - if err := mapstructure.Decode(r, &requestFields); err == nil { - log.RequestIDLogger(r).Debug(requestFields) - } - // errors should always be in JSON - w.Header()["Content-Type"] = []string{"application/json"} - if e, ok := err.(goaerrors.Error); ok && e.Code() == http.StatusUnauthorized { - // this is set directly so the header name is not canonicalized - issuers := []string{} - for iss := range config.FromContext(r.Context()).OIDCIssuers { - issuers = append(issuers, "Bearer realm=\""+iss+"\",scope=\"openid email\"") - } - w.Header()["WWW-Authenticate"] = []string{strings.Join(issuers, ", ")} - w.WriteHeader(int(e.Code())) - // mask actual auth reason from client - err = goaerrors.New(e.Code(), "authentication credentials could not be validated") - } - goaerrors.ServeError(w, r, err) -} - -//go:embed fulcioHomePage.html -var homePageBytes []byte - -func serveStaticContent(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/" { - w.Header().Add("Content-Type", "text/html") - w.WriteHeader(200) - _, _ = w.Write(homePageBytes) - return - } - handler.ServeHTTP(w, r) - }) -} diff --git a/pkg/generated/restapi/doc.go b/pkg/generated/restapi/doc.go deleted file mode 100644 index 78f6afc41..000000000 --- a/pkg/generated/restapi/doc.go +++ /dev/null @@ -1,34 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. -// -// Copyright 2021 The Sigstore Authors. -// -// 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 restapi Fulcio -// -// Schemes: -// http -// https -// Host: fulcio.sigstore.dev -// BasePath: /api/v1 -// Version: 1.0.0 -// -// Consumes: -// - application/json -// -// Produces: -// - application/pem-certificate-chain -// -// swagger:meta -package restapi diff --git a/pkg/generated/restapi/embedded_spec.go b/pkg/generated/restapi/embedded_spec.go deleted file mode 100644 index 95f9de7d2..000000000 --- a/pkg/generated/restapi/embedded_spec.go +++ /dev/null @@ -1,396 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 restapi - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "encoding/json" -) - -var ( - // SwaggerJSON embedded version of the swagger document used at generation time - SwaggerJSON json.RawMessage - // FlatSwaggerJSON embedded flattened version of the swagger document used at generation time - FlatSwaggerJSON json.RawMessage -) - -func init() { - SwaggerJSON = json.RawMessage([]byte(`{ - "schemes": [ - "http", - "https" - ], - "swagger": "2.0", - "info": { - "title": "Fulcio", - "version": "1.0.0" - }, - "host": "fulcio.sigstore.dev", - "basePath": "/api/v1", - "paths": { - "/signingCert": { - "post": { - "security": [ - { - "Bearer": [] - } - ], - "description": "create a cert, return content with a location header (with URL to CTL entry)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/pem-certificate-chain" - ], - "operationId": "signingCert", - "parameters": [ - { - "description": "Request for signing certificate", - "name": "CertificateRequest", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/CertificateRequest" - } - } - ], - "responses": { - "201": { - "description": "Generated Certificate Chain", - "schema": { - "type": "string" - }, - "headers": { - "SCT": { - "type": "string", - "format": "byte", - "description": "Signed Certificate Timestamp from Entry in CT Log" - } - } - }, - "400": { - "$ref": "#/responses/BadRequest" - }, - "401": { - "$ref": "#/responses/Unauthorized" - }, - "default": { - "$ref": "#/responses/InternalServerError" - } - } - } - } - }, - "definitions": { - "CertificateRequest": { - "type": "object", - "required": [ - "publicKey", - "signedEmailAddress" - ], - "properties": { - "publicKey": { - "type": "object", - "required": [ - "content" - ], - "properties": { - "algorithm": { - "type": "string", - "enum": [ - "ecdsa" - ] - }, - "content": { - "type": "string", - "format": "byte" - } - } - }, - "signedEmailAddress": { - "type": "string", - "format": "byte" - } - } - }, - "Error": { - "type": "object", - "properties": { - "code": { - "type": "integer" - }, - "message": { - "type": "string" - } - } - } - }, - "responses": { - "BadRequest": { - "description": "The content supplied to the server was invalid", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - } - } - }, - "InternalServerError": { - "description": "There was an internal error in the server while processing the request", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - } - } - }, - "Unauthorized": { - "description": "The request could not be authorized", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - }, - "WWW-Authenticate": { - "type": "string", - "description": "Information about required authentication to access server" - } - } - } - }, - "securityDefinitions": { - "Bearer": { - "type": "apiKey", - "name": "Authorization", - "in": "header" - } - } -}`)) - FlatSwaggerJSON = json.RawMessage([]byte(`{ - "schemes": [ - "http", - "https" - ], - "swagger": "2.0", - "info": { - "title": "Fulcio", - "version": "1.0.0" - }, - "host": "fulcio.sigstore.dev", - "basePath": "/api/v1", - "paths": { - "/signingCert": { - "post": { - "security": [ - { - "Bearer": [] - } - ], - "description": "create a cert, return content with a location header (with URL to CTL entry)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/pem-certificate-chain" - ], - "operationId": "signingCert", - "parameters": [ - { - "description": "Request for signing certificate", - "name": "CertificateRequest", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/CertificateRequest" - } - } - ], - "responses": { - "201": { - "description": "Generated Certificate Chain", - "schema": { - "type": "string" - }, - "headers": { - "SCT": { - "type": "string", - "format": "byte", - "description": "Signed Certificate Timestamp from Entry in CT Log" - } - } - }, - "400": { - "description": "The content supplied to the server was invalid", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - } - } - }, - "401": { - "description": "The request could not be authorized", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - }, - "WWW-Authenticate": { - "type": "string", - "description": "Information about required authentication to access server" - } - } - }, - "default": { - "description": "There was an internal error in the server while processing the request", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - } - } - } - } - } - } - }, - "definitions": { - "CertificateRequest": { - "type": "object", - "required": [ - "publicKey", - "signedEmailAddress" - ], - "properties": { - "publicKey": { - "type": "object", - "required": [ - "content" - ], - "properties": { - "algorithm": { - "type": "string", - "enum": [ - "ecdsa" - ] - }, - "content": { - "type": "string", - "format": "byte" - } - } - }, - "signedEmailAddress": { - "type": "string", - "format": "byte" - } - } - }, - "CertificateRequestPublicKey": { - "type": "object", - "required": [ - "content" - ], - "properties": { - "algorithm": { - "type": "string", - "enum": [ - "ecdsa" - ] - }, - "content": { - "type": "string", - "format": "byte" - } - } - }, - "Error": { - "type": "object", - "properties": { - "code": { - "type": "integer" - }, - "message": { - "type": "string" - } - } - } - }, - "responses": { - "BadRequest": { - "description": "The content supplied to the server was invalid", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - } - } - }, - "InternalServerError": { - "description": "There was an internal error in the server while processing the request", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - } - } - }, - "Unauthorized": { - "description": "The request could not be authorized", - "schema": { - "$ref": "#/definitions/Error" - }, - "headers": { - "Content-Type": { - "type": "string" - }, - "WWW-Authenticate": { - "type": "string", - "description": "Information about required authentication to access server" - } - } - } - }, - "securityDefinitions": { - "Bearer": { - "type": "apiKey", - "name": "Authorization", - "in": "header" - } - } -}`)) -} diff --git a/pkg/generated/restapi/fulcioHomePage.html b/pkg/generated/restapi/fulcioHomePage.html deleted file mode 100644 index d257385e0..000000000 --- a/pkg/generated/restapi/fulcioHomePage.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - sigstore - - - - - -

- Fulcio Server -

-

- A non-profit, public good software signing & transparency service. -

To learn more visit Sigstore project page

-

- - - diff --git a/pkg/generated/restapi/operations/fulcio_server_api.go b/pkg/generated/restapi/operations/fulcio_server_api.go deleted file mode 100644 index 35944523e..000000000 --- a/pkg/generated/restapi/operations/fulcio_server_api.go +++ /dev/null @@ -1,351 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "fmt" - "io" - "net/http" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/loads" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/middleware" - "github.com/go-openapi/runtime/security" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - - "github.com/coreos/go-oidc/v3/oidc" -) - -// NewFulcioServerAPI creates a new FulcioServer instance -func NewFulcioServerAPI(spec *loads.Document) *FulcioServerAPI { - return &FulcioServerAPI{ - handlers: make(map[string]map[string]http.Handler), - formats: strfmt.Default, - defaultConsumes: "application/json", - defaultProduces: "application/json", - customConsumers: make(map[string]runtime.Consumer), - customProducers: make(map[string]runtime.Producer), - PreServerShutdown: func() {}, - ServerShutdown: func() {}, - spec: spec, - useSwaggerUI: false, - ServeError: errors.ServeError, - BasicAuthenticator: security.BasicAuth, - APIKeyAuthenticator: security.APIKeyAuth, - BearerAuthenticator: security.BearerAuth, - - JSONConsumer: runtime.JSONConsumer(), - - ApplicationPemCertificateChainProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { - return errors.NotImplemented("applicationPemCertificateChain producer has not yet been implemented") - }), - - SigningCertHandler: SigningCertHandlerFunc(func(params SigningCertParams, principal *oidc.IDToken) middleware.Responder { - return middleware.NotImplemented("operation SigningCert has not yet been implemented") - }), - - // Applies when the "Authorization" header is set - BearerAuth: func(token string) (*oidc.IDToken, error) { - return nil, errors.NotImplemented("api key auth (Bearer) Authorization from header param [Authorization] has not yet been implemented") - }, - // default authorizer is authorized meaning no requests are blocked - APIAuthorizer: security.Authorized(), - } -} - -/*FulcioServerAPI the fulcio server API */ -type FulcioServerAPI struct { - spec *loads.Document - context *middleware.Context - handlers map[string]map[string]http.Handler - formats strfmt.Registry - customConsumers map[string]runtime.Consumer - customProducers map[string]runtime.Producer - defaultConsumes string - defaultProduces string - Middleware func(middleware.Builder) http.Handler - useSwaggerUI bool - - // BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function. - // It has a default implementation in the security package, however you can replace it for your particular usage. - BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator - - // APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function. - // It has a default implementation in the security package, however you can replace it for your particular usage. - APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator - - // BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function. - // It has a default implementation in the security package, however you can replace it for your particular usage. - BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator - - // JSONConsumer registers a consumer for the following mime types: - // - application/json - JSONConsumer runtime.Consumer - - // ApplicationPemCertificateChainProducer registers a producer for the following mime types: - // - application/pem-certificate-chain - ApplicationPemCertificateChainProducer runtime.Producer - - // BearerAuth registers a function that takes a token and returns a principal - // it performs authentication based on an api key Authorization provided in the header - BearerAuth func(string) (*oidc.IDToken, error) - - // APIAuthorizer provides access control (ACL/RBAC/ABAC) by providing access to the request and authenticated principal - APIAuthorizer runtime.Authorizer - - // SigningCertHandler sets the operation handler for the signing cert operation - SigningCertHandler SigningCertHandler - - // ServeError is called when an error is received, there is a default handler - // but you can set your own with this - ServeError func(http.ResponseWriter, *http.Request, error) - - // PreServerShutdown is called before the HTTP(S) server is shutdown - // This allows for custom functions to get executed before the HTTP(S) server stops accepting traffic - PreServerShutdown func() - - // ServerShutdown is called when the HTTP(S) server is shut down and done - // handling all active connections and does not accept connections any more - ServerShutdown func() - - // Custom command line argument groups with their descriptions - CommandLineOptionsGroups []swag.CommandLineOptionsGroup - - // User defined logger function. - Logger func(string, ...interface{}) -} - -// UseRedoc for documentation at /docs -func (o *FulcioServerAPI) UseRedoc() { - o.useSwaggerUI = false -} - -// UseSwaggerUI for documentation at /docs -func (o *FulcioServerAPI) UseSwaggerUI() { - o.useSwaggerUI = true -} - -// SetDefaultProduces sets the default produces media type -func (o *FulcioServerAPI) SetDefaultProduces(mediaType string) { - o.defaultProduces = mediaType -} - -// SetDefaultConsumes returns the default consumes media type -func (o *FulcioServerAPI) SetDefaultConsumes(mediaType string) { - o.defaultConsumes = mediaType -} - -// SetSpec sets a spec that will be served for the clients. -func (o *FulcioServerAPI) SetSpec(spec *loads.Document) { - o.spec = spec -} - -// DefaultProduces returns the default produces media type -func (o *FulcioServerAPI) DefaultProduces() string { - return o.defaultProduces -} - -// DefaultConsumes returns the default consumes media type -func (o *FulcioServerAPI) DefaultConsumes() string { - return o.defaultConsumes -} - -// Formats returns the registered string formats -func (o *FulcioServerAPI) Formats() strfmt.Registry { - return o.formats -} - -// RegisterFormat registers a custom format validator -func (o *FulcioServerAPI) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) { - o.formats.Add(name, format, validator) -} - -// Validate validates the registrations in the FulcioServerAPI -func (o *FulcioServerAPI) Validate() error { - var unregistered []string - - if o.JSONConsumer == nil { - unregistered = append(unregistered, "JSONConsumer") - } - - if o.ApplicationPemCertificateChainProducer == nil { - unregistered = append(unregistered, "ApplicationPemCertificateChainProducer") - } - - if o.BearerAuth == nil { - unregistered = append(unregistered, "AuthorizationAuth") - } - - if o.SigningCertHandler == nil { - unregistered = append(unregistered, "SigningCertHandler") - } - - if len(unregistered) > 0 { - return fmt.Errorf("missing registration: %s", strings.Join(unregistered, ", ")) - } - - return nil -} - -// ServeErrorFor gets a error handler for a given operation id -func (o *FulcioServerAPI) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) { - return o.ServeError -} - -// AuthenticatorsFor gets the authenticators for the specified security schemes -func (o *FulcioServerAPI) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { - result := make(map[string]runtime.Authenticator) - for name := range schemes { - switch name { - case "Bearer": - scheme := schemes[name] - result[name] = o.APIKeyAuthenticator(scheme.Name, scheme.In, func(token string) (interface{}, error) { - return o.BearerAuth(token) - }) - - } - } - return result -} - -// Authorizer returns the registered authorizer -func (o *FulcioServerAPI) Authorizer() runtime.Authorizer { - return o.APIAuthorizer -} - -// ConsumersFor gets the consumers for the specified media types. -// MIME type parameters are ignored here. -func (o *FulcioServerAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { - result := make(map[string]runtime.Consumer, len(mediaTypes)) - for _, mt := range mediaTypes { - switch mt { - case "application/json": - result["application/json"] = o.JSONConsumer - } - - if c, ok := o.customConsumers[mt]; ok { - result[mt] = c - } - } - return result -} - -// ProducersFor gets the producers for the specified media types. -// MIME type parameters are ignored here. -func (o *FulcioServerAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer { - result := make(map[string]runtime.Producer, len(mediaTypes)) - for _, mt := range mediaTypes { - switch mt { - case "application/pem-certificate-chain": - result["application/pem-certificate-chain"] = o.ApplicationPemCertificateChainProducer - } - - if p, ok := o.customProducers[mt]; ok { - result[mt] = p - } - } - return result -} - -// HandlerFor gets a http.Handler for the provided operation method and path -func (o *FulcioServerAPI) HandlerFor(method, path string) (http.Handler, bool) { - if o.handlers == nil { - return nil, false - } - um := strings.ToUpper(method) - if _, ok := o.handlers[um]; !ok { - return nil, false - } - if path == "/" { - path = "" - } - h, ok := o.handlers[um][path] - return h, ok -} - -// Context returns the middleware context for the fulcio server API -func (o *FulcioServerAPI) Context() *middleware.Context { - if o.context == nil { - o.context = middleware.NewRoutableContext(o.spec, o, nil) - } - - return o.context -} - -func (o *FulcioServerAPI) initHandlerCache() { - o.Context() // don't care about the result, just that the initialization happened - if o.handlers == nil { - o.handlers = make(map[string]map[string]http.Handler) - } - - if o.handlers["POST"] == nil { - o.handlers["POST"] = make(map[string]http.Handler) - } - o.handlers["POST"]["/signingCert"] = NewSigningCert(o.context, o.SigningCertHandler) -} - -// Serve creates a http handler to serve the API over HTTP -// can be used directly in http.ListenAndServe(":8000", api.Serve(nil)) -func (o *FulcioServerAPI) Serve(builder middleware.Builder) http.Handler { - o.Init() - - if o.Middleware != nil { - return o.Middleware(builder) - } - if o.useSwaggerUI { - return o.context.APIHandlerSwaggerUI(builder) - } - return o.context.APIHandler(builder) -} - -// Init allows you to just initialize the handler cache, you can then recompose the middleware as you see fit -func (o *FulcioServerAPI) Init() { - if len(o.handlers) == 0 { - o.initHandlerCache() - } -} - -// RegisterConsumer allows you to add (or override) a consumer for a media type. -func (o *FulcioServerAPI) RegisterConsumer(mediaType string, consumer runtime.Consumer) { - o.customConsumers[mediaType] = consumer -} - -// RegisterProducer allows you to add (or override) a producer for a media type. -func (o *FulcioServerAPI) RegisterProducer(mediaType string, producer runtime.Producer) { - o.customProducers[mediaType] = producer -} - -// AddMiddlewareFor adds a http middleware to existing handler -func (o *FulcioServerAPI) AddMiddlewareFor(method, path string, builder middleware.Builder) { - um := strings.ToUpper(method) - if path == "/" { - path = "" - } - o.Init() - if h, ok := o.handlers[um][path]; ok { - o.handlers[method][path] = builder(h) - } -} diff --git a/pkg/generated/restapi/operations/signing_cert.go b/pkg/generated/restapi/operations/signing_cert.go deleted file mode 100644 index 909acbbaa..000000000 --- a/pkg/generated/restapi/operations/signing_cert.go +++ /dev/null @@ -1,87 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the generate command - -import ( - "net/http" - - "github.com/go-openapi/runtime/middleware" - - "github.com/coreos/go-oidc/v3/oidc" -) - -// SigningCertHandlerFunc turns a function with the right signature into a signing cert handler -type SigningCertHandlerFunc func(SigningCertParams, *oidc.IDToken) middleware.Responder - -// Handle executing the request and returning a response -func (fn SigningCertHandlerFunc) Handle(params SigningCertParams, principal *oidc.IDToken) middleware.Responder { - return fn(params, principal) -} - -// SigningCertHandler interface for that can handle valid signing cert params -type SigningCertHandler interface { - Handle(SigningCertParams, *oidc.IDToken) middleware.Responder -} - -// NewSigningCert creates a new http.Handler for the signing cert operation -func NewSigningCert(ctx *middleware.Context, handler SigningCertHandler) *SigningCert { - return &SigningCert{Context: ctx, Handler: handler} -} - -/* SigningCert swagger:route POST /signingCert signingCert - -create a cert, return content with a location header (with URL to CTL entry) - -*/ -type SigningCert struct { - Context *middleware.Context - Handler SigningCertHandler -} - -func (o *SigningCert) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - route, rCtx, _ := o.Context.RouteInfo(r) - if rCtx != nil { - *r = *rCtx - } - var Params = NewSigningCertParams() - uprinc, aCtx, err := o.Context.Authorize(r, route) - if err != nil { - o.Context.Respond(rw, r, route.Produces, route, err) - return - } - if aCtx != nil { - *r = *aCtx - } - var principal *oidc.IDToken - if uprinc != nil { - principal = uprinc.(*oidc.IDToken) // this is really a oidc.IDToken, I promise - } - - if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params - o.Context.Respond(rw, r, route.Produces, route, err) - return - } - - res := o.Handler.Handle(Params, principal) // actually handle the request - o.Context.Respond(rw, r, route.Produces, route, res) - -} diff --git a/pkg/generated/restapi/operations/signing_cert_parameters.go b/pkg/generated/restapi/operations/signing_cert_parameters.go deleted file mode 100644 index d334bc90e..000000000 --- a/pkg/generated/restapi/operations/signing_cert_parameters.go +++ /dev/null @@ -1,101 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "context" - "io" - "net/http" - - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/middleware" - "github.com/go-openapi/validate" - - "github.com/sigstore/fulcio/pkg/generated/models" -) - -// NewSigningCertParams creates a new SigningCertParams object -// -// There are no default values defined in the spec. -func NewSigningCertParams() SigningCertParams { - - return SigningCertParams{} -} - -// SigningCertParams contains all the bound params for the signing cert operation -// typically these are obtained from a http.Request -// -// swagger:parameters signingCert -type SigningCertParams struct { - - // HTTP Request Object - HTTPRequest *http.Request `json:"-"` - - /*Request for signing certificate - Required: true - In: body - */ - CertificateRequest *models.CertificateRequest -} - -// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface -// for simple values it will use straight method calls. -// -// To ensure default values, the struct must have been initialized with NewSigningCertParams() beforehand. -func (o *SigningCertParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { - var res []error - - o.HTTPRequest = r - - if runtime.HasBody(r) { - defer r.Body.Close() - var body models.CertificateRequest - if err := route.Consumer.Consume(r.Body, &body); err != nil { - if err == io.EOF { - res = append(res, errors.Required("certificateRequest", "body", "")) - } else { - res = append(res, errors.NewParseError("certificateRequest", "body", "", err)) - } - } else { - // validate body object - if err := body.Validate(route.Formats); err != nil { - res = append(res, err) - } - - ctx := validate.WithOperationRequest(context.Background()) - if err := body.ContextValidate(ctx, route.Formats); err != nil { - res = append(res, err) - } - - if len(res) == 0 { - o.CertificateRequest = &body - } - } - } else { - res = append(res, errors.Required("certificateRequest", "body", "")) - } - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} diff --git a/pkg/generated/restapi/operations/signing_cert_responses.go b/pkg/generated/restapi/operations/signing_cert_responses.go deleted file mode 100644 index ae7943c4c..000000000 --- a/pkg/generated/restapi/operations/signing_cert_responses.go +++ /dev/null @@ -1,329 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "net/http" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" - - "github.com/sigstore/fulcio/pkg/generated/models" -) - -// SigningCertCreatedCode is the HTTP code returned for type SigningCertCreated -const SigningCertCreatedCode int = 201 - -/*SigningCertCreated Generated Certificate Chain - -swagger:response signingCertCreated -*/ -type SigningCertCreated struct { - /*Signed Certificate Timestamp from Entry in CT Log - - */ - SCT strfmt.Base64 `json:"SCT"` - - /* - In: Body - */ - Payload string `json:"body,omitempty"` -} - -// NewSigningCertCreated creates SigningCertCreated with default headers values -func NewSigningCertCreated() *SigningCertCreated { - - return &SigningCertCreated{} -} - -// WithSCT adds the sct to the signing cert created response -func (o *SigningCertCreated) WithSCT(sct strfmt.Base64) *SigningCertCreated { - o.SCT = sct - return o -} - -// SetSCT sets the sct to the signing cert created response -func (o *SigningCertCreated) SetSCT(sct strfmt.Base64) { - o.SCT = sct -} - -// WithPayload adds the payload to the signing cert created response -func (o *SigningCertCreated) WithPayload(payload string) *SigningCertCreated { - o.Payload = payload - return o -} - -// SetPayload sets the payload to the signing cert created response -func (o *SigningCertCreated) SetPayload(payload string) { - o.Payload = payload -} - -// WriteResponse to the client -func (o *SigningCertCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - // response header SCT - - sct := o.SCT.String() - if sct != "" { - rw.Header().Set("SCT", sct) - } - - rw.WriteHeader(201) - payload := o.Payload - if err := producer.Produce(rw, payload); err != nil { - panic(err) // let the recovery middleware deal with this - } -} - -// SigningCertBadRequestCode is the HTTP code returned for type SigningCertBadRequest -const SigningCertBadRequestCode int = 400 - -/*SigningCertBadRequest The content supplied to the server was invalid - -swagger:response signingCertBadRequest -*/ -type SigningCertBadRequest struct { - /* - - */ - ContentType string `json:"Content-Type"` - - /* - In: Body - */ - Payload *models.Error `json:"body,omitempty"` -} - -// NewSigningCertBadRequest creates SigningCertBadRequest with default headers values -func NewSigningCertBadRequest() *SigningCertBadRequest { - - return &SigningCertBadRequest{} -} - -// WithContentType adds the contentType to the signing cert bad request response -func (o *SigningCertBadRequest) WithContentType(contentType string) *SigningCertBadRequest { - o.ContentType = contentType - return o -} - -// SetContentType sets the contentType to the signing cert bad request response -func (o *SigningCertBadRequest) SetContentType(contentType string) { - o.ContentType = contentType -} - -// WithPayload adds the payload to the signing cert bad request response -func (o *SigningCertBadRequest) WithPayload(payload *models.Error) *SigningCertBadRequest { - o.Payload = payload - return o -} - -// SetPayload sets the payload to the signing cert bad request response -func (o *SigningCertBadRequest) SetPayload(payload *models.Error) { - o.Payload = payload -} - -// WriteResponse to the client -func (o *SigningCertBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - // response header Content-Type - - contentType := o.ContentType - if contentType != "" { - rw.Header().Set("Content-Type", contentType) - } - - rw.WriteHeader(400) - if o.Payload != nil { - payload := o.Payload - if err := producer.Produce(rw, payload); err != nil { - panic(err) // let the recovery middleware deal with this - } - } -} - -// SigningCertUnauthorizedCode is the HTTP code returned for type SigningCertUnauthorized -const SigningCertUnauthorizedCode int = 401 - -/*SigningCertUnauthorized The request could not be authorized - -swagger:response signingCertUnauthorized -*/ -type SigningCertUnauthorized struct { - /* - - */ - ContentType string `json:"Content-Type"` - /*Information about required authentication to access server - - */ - WWWAuthenticate string `json:"WWW-Authenticate"` - - /* - In: Body - */ - Payload *models.Error `json:"body,omitempty"` -} - -// NewSigningCertUnauthorized creates SigningCertUnauthorized with default headers values -func NewSigningCertUnauthorized() *SigningCertUnauthorized { - - return &SigningCertUnauthorized{} -} - -// WithContentType adds the contentType to the signing cert unauthorized response -func (o *SigningCertUnauthorized) WithContentType(contentType string) *SigningCertUnauthorized { - o.ContentType = contentType - return o -} - -// SetContentType sets the contentType to the signing cert unauthorized response -func (o *SigningCertUnauthorized) SetContentType(contentType string) { - o.ContentType = contentType -} - -// WithWWWAuthenticate adds the wWWAuthenticate to the signing cert unauthorized response -func (o *SigningCertUnauthorized) WithWWWAuthenticate(wWWAuthenticate string) *SigningCertUnauthorized { - o.WWWAuthenticate = wWWAuthenticate - return o -} - -// SetWWWAuthenticate sets the wWWAuthenticate to the signing cert unauthorized response -func (o *SigningCertUnauthorized) SetWWWAuthenticate(wWWAuthenticate string) { - o.WWWAuthenticate = wWWAuthenticate -} - -// WithPayload adds the payload to the signing cert unauthorized response -func (o *SigningCertUnauthorized) WithPayload(payload *models.Error) *SigningCertUnauthorized { - o.Payload = payload - return o -} - -// SetPayload sets the payload to the signing cert unauthorized response -func (o *SigningCertUnauthorized) SetPayload(payload *models.Error) { - o.Payload = payload -} - -// WriteResponse to the client -func (o *SigningCertUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - // response header Content-Type - - contentType := o.ContentType - if contentType != "" { - rw.Header().Set("Content-Type", contentType) - } - - // response header WWW-Authenticate - - wWWAuthenticate := o.WWWAuthenticate - if wWWAuthenticate != "" { - rw.Header().Set("WWW-Authenticate", wWWAuthenticate) - } - - rw.WriteHeader(401) - if o.Payload != nil { - payload := o.Payload - if err := producer.Produce(rw, payload); err != nil { - panic(err) // let the recovery middleware deal with this - } - } -} - -/*SigningCertDefault There was an internal error in the server while processing the request - -swagger:response signingCertDefault -*/ -type SigningCertDefault struct { - _statusCode int - /* - - */ - ContentType string `json:"Content-Type"` - - /* - In: Body - */ - Payload *models.Error `json:"body,omitempty"` -} - -// NewSigningCertDefault creates SigningCertDefault with default headers values -func NewSigningCertDefault(code int) *SigningCertDefault { - if code <= 0 { - code = 500 - } - - return &SigningCertDefault{ - _statusCode: code, - } -} - -// WithStatusCode adds the status to the signing cert default response -func (o *SigningCertDefault) WithStatusCode(code int) *SigningCertDefault { - o._statusCode = code - return o -} - -// SetStatusCode sets the status to the signing cert default response -func (o *SigningCertDefault) SetStatusCode(code int) { - o._statusCode = code -} - -// WithContentType adds the contentType to the signing cert default response -func (o *SigningCertDefault) WithContentType(contentType string) *SigningCertDefault { - o.ContentType = contentType - return o -} - -// SetContentType sets the contentType to the signing cert default response -func (o *SigningCertDefault) SetContentType(contentType string) { - o.ContentType = contentType -} - -// WithPayload adds the payload to the signing cert default response -func (o *SigningCertDefault) WithPayload(payload *models.Error) *SigningCertDefault { - o.Payload = payload - return o -} - -// SetPayload sets the payload to the signing cert default response -func (o *SigningCertDefault) SetPayload(payload *models.Error) { - o.Payload = payload -} - -// WriteResponse to the client -func (o *SigningCertDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - - // response header Content-Type - - contentType := o.ContentType - if contentType != "" { - rw.Header().Set("Content-Type", contentType) - } - - rw.WriteHeader(o._statusCode) - if o.Payload != nil { - payload := o.Payload - if err := producer.Produce(rw, payload); err != nil { - panic(err) // let the recovery middleware deal with this - } - } -} diff --git a/pkg/generated/restapi/operations/signing_cert_urlbuilder.go b/pkg/generated/restapi/operations/signing_cert_urlbuilder.go deleted file mode 100644 index e2e475075..000000000 --- a/pkg/generated/restapi/operations/signing_cert_urlbuilder.go +++ /dev/null @@ -1,103 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 operations - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the generate command - -import ( - "errors" - "net/url" - golangswaggerpaths "path" -) - -// SigningCertURL generates an URL for the signing cert operation -type SigningCertURL struct { - _basePath string -} - -// WithBasePath sets the base path for this url builder, only required when it's different from the -// base path specified in the swagger spec. -// When the value of the base path is an empty string -func (o *SigningCertURL) WithBasePath(bp string) *SigningCertURL { - o.SetBasePath(bp) - return o -} - -// SetBasePath sets the base path for this url builder, only required when it's different from the -// base path specified in the swagger spec. -// When the value of the base path is an empty string -func (o *SigningCertURL) SetBasePath(bp string) { - o._basePath = bp -} - -// Build a url path and query string -func (o *SigningCertURL) Build() (*url.URL, error) { - var _result url.URL - - var _path = "/signingCert" - - _basePath := o._basePath - if _basePath == "" { - _basePath = "/api/v1" - } - _result.Path = golangswaggerpaths.Join(_basePath, _path) - - return &_result, nil -} - -// Must is a helper function to panic when the url builder returns an error -func (o *SigningCertURL) Must(u *url.URL, err error) *url.URL { - if err != nil { - panic(err) - } - if u == nil { - panic("url can't be nil") - } - return u -} - -// String returns the string representation of the path with query string -func (o *SigningCertURL) String() string { - return o.Must(o.Build()).String() -} - -// BuildFull builds a full url with scheme, host, path and query string -func (o *SigningCertURL) BuildFull(scheme, host string) (*url.URL, error) { - if scheme == "" { - return nil, errors.New("scheme is required for a full url on SigningCertURL") - } - if host == "" { - return nil, errors.New("host is required for a full url on SigningCertURL") - } - - base, err := o.Build() - if err != nil { - return nil, err - } - - base.Scheme = scheme - base.Host = host - return base, nil -} - -// StringFull returns the string representation of a complete url -func (o *SigningCertURL) StringFull(scheme, host string) string { - return o.Must(o.BuildFull(scheme, host)).String() -} diff --git a/pkg/generated/restapi/server.go b/pkg/generated/restapi/server.go deleted file mode 100644 index a2acb11bc..000000000 --- a/pkg/generated/restapi/server.go +++ /dev/null @@ -1,629 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// 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 restapi - -import ( - "context" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "io/ioutil" - "log" - "net" - "net/http" - "os" - "os/signal" - "strconv" - "sync" - "sync/atomic" - "syscall" - "time" - - "github.com/go-openapi/runtime/flagext" - "github.com/go-openapi/swag" - flag "github.com/spf13/pflag" - "golang.org/x/net/netutil" - - "github.com/sigstore/fulcio/pkg/generated/restapi/operations" -) - -const ( - schemeHTTP = "http" - schemeHTTPS = "https" - schemeUnix = "unix" -) - -var defaultSchemes []string - -func init() { - defaultSchemes = []string{ - schemeHTTP, - schemeHTTPS, - } -} - -var ( - enabledListeners []string - cleanupTimeout time.Duration - gracefulTimeout time.Duration - maxHeaderSize flagext.ByteSize - - socketPath string - - host string - port int - listenLimit int - keepAlive time.Duration - readTimeout time.Duration - writeTimeout time.Duration - - tlsHost string - tlsPort int - tlsListenLimit int - tlsKeepAlive time.Duration - tlsReadTimeout time.Duration - tlsWriteTimeout time.Duration - tlsCertificate string - tlsCertificateKey string - tlsCACertificate string -) - -func init() { - maxHeaderSize = flagext.ByteSize(1000000) - - flag.StringSliceVar(&enabledListeners, "scheme", defaultSchemes, "the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec") - - flag.DurationVar(&cleanupTimeout, "cleanup-timeout", 10*time.Second, "grace period for which to wait before killing idle connections") - flag.DurationVar(&gracefulTimeout, "graceful-timeout", 15*time.Second, "grace period for which to wait before shutting down the server") - flag.Var(&maxHeaderSize, "max-header-size", "controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body") - - flag.StringVar(&socketPath, "socket-path", "/var/run/todo-list.sock", "the unix socket to listen on") - - flag.StringVar(&host, "host", "localhost", "the IP to listen on") - flag.IntVar(&port, "port", 0, "the port to listen on for insecure connections, defaults to a random value") - flag.IntVar(&listenLimit, "listen-limit", 0, "limit the number of outstanding requests") - flag.DurationVar(&keepAlive, "keep-alive", 3*time.Minute, "sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)") - flag.DurationVar(&readTimeout, "read-timeout", 30*time.Second, "maximum duration before timing out read of the request") - flag.DurationVar(&writeTimeout, "write-timeout", 30*time.Second, "maximum duration before timing out write of the response") - - flag.StringVar(&tlsHost, "tls-host", "localhost", "the IP to listen on") - flag.IntVar(&tlsPort, "tls-port", 0, "the port to listen on for secure connections, defaults to a random value") - flag.StringVar(&tlsCertificate, "tls-certificate", "", "the certificate file to use for secure connections") - flag.StringVar(&tlsCertificateKey, "tls-key", "", "the private key file to use for secure connections (without passphrase)") - flag.StringVar(&tlsCACertificate, "tls-ca", "", "the certificate authority certificate file to be used with mutual tls auth") - flag.IntVar(&tlsListenLimit, "tls-listen-limit", 0, "limit the number of outstanding requests") - flag.DurationVar(&tlsKeepAlive, "tls-keep-alive", 3*time.Minute, "sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)") - flag.DurationVar(&tlsReadTimeout, "tls-read-timeout", 30*time.Second, "maximum duration before timing out read of the request") - flag.DurationVar(&tlsWriteTimeout, "tls-write-timeout", 30*time.Second, "maximum duration before timing out write of the response") -} - -func stringEnvOverride(orig string, def string, keys ...string) string { - for _, k := range keys { - if os.Getenv(k) != "" { - return os.Getenv(k) - } - } - if def != "" && orig == "" { - return def - } - return orig -} - -func intEnvOverride(orig int, def int, keys ...string) int { - for _, k := range keys { - if os.Getenv(k) != "" { - v, err := strconv.Atoi(os.Getenv(k)) - if err != nil { - fmt.Fprintln(os.Stderr, k, "is not a valid number") - os.Exit(1) - } - return v - } - } - if def != 0 && orig == 0 { - return def - } - return orig -} - -// NewServer creates a new api fulcio server server but does not configure it -func NewServer(api *operations.FulcioServerAPI) *Server { - s := new(Server) - - s.EnabledListeners = enabledListeners - s.CleanupTimeout = cleanupTimeout - s.GracefulTimeout = gracefulTimeout - s.MaxHeaderSize = maxHeaderSize - s.SocketPath = socketPath - s.Host = stringEnvOverride(host, "", "HOST") - s.Port = intEnvOverride(port, 0, "PORT") - s.ListenLimit = listenLimit - s.KeepAlive = keepAlive - s.ReadTimeout = readTimeout - s.WriteTimeout = writeTimeout - s.TLSHost = stringEnvOverride(tlsHost, s.Host, "TLS_HOST", "HOST") - s.TLSPort = intEnvOverride(tlsPort, 0, "TLS_PORT") - s.TLSCertificate = stringEnvOverride(tlsCertificate, "", "TLS_CERTIFICATE") - s.TLSCertificateKey = stringEnvOverride(tlsCertificateKey, "", "TLS_PRIVATE_KEY") - s.TLSCACertificate = stringEnvOverride(tlsCACertificate, "", "TLS_CA_CERTIFICATE") - s.TLSListenLimit = tlsListenLimit - s.TLSKeepAlive = tlsKeepAlive - s.TLSReadTimeout = tlsReadTimeout - s.TLSWriteTimeout = tlsWriteTimeout - s.shutdown = make(chan struct{}) - s.api = api - s.interrupt = make(chan os.Signal, 1) - return s -} - -// ConfigureAPI configures the API and handlers. -func (s *Server) ConfigureAPI() { - if s.api != nil { - s.handler = configureAPI(s.api) - } -} - -// ConfigureFlags configures the additional flags defined by the handlers. Needs to be called before the parser.Parse -func (s *Server) ConfigureFlags() { - if s.api != nil { - configureFlags(s.api) - } -} - -// Server for the fulcio server API -type Server struct { - EnabledListeners []string - CleanupTimeout time.Duration - GracefulTimeout time.Duration - MaxHeaderSize flagext.ByteSize - - SocketPath string - domainSocketL net.Listener - - Host string - Port int - ListenLimit int - KeepAlive time.Duration - ReadTimeout time.Duration - WriteTimeout time.Duration - httpServerL net.Listener - - TLSHost string - TLSPort int - TLSCertificate string - TLSCertificateKey string - TLSCACertificate string - TLSListenLimit int - TLSKeepAlive time.Duration - TLSReadTimeout time.Duration - TLSWriteTimeout time.Duration - httpsServerL net.Listener - - api *operations.FulcioServerAPI - handler http.Handler - hasListeners bool - shutdown chan struct{} - shuttingDown int32 - interrupted bool - interrupt chan os.Signal -} - -// Logf logs message either via defined user logger or via system one if no user logger is defined. -func (s *Server) Logf(f string, args ...interface{}) { - if s.api != nil && s.api.Logger != nil { - s.api.Logger(f, args...) - } else { - log.Printf(f, args...) - } -} - -// Fatalf logs message either via defined user logger or via system one if no user logger is defined. -// Exits with non-zero status after printing -func (s *Server) Fatalf(f string, args ...interface{}) { - if s.api != nil && s.api.Logger != nil { - s.api.Logger(f, args...) - os.Exit(1) - } else { - log.Fatalf(f, args...) - } -} - -// SetAPI configures the server with the specified API. Needs to be called before Serve -func (s *Server) SetAPI(api *operations.FulcioServerAPI) { - if api == nil { - s.api = nil - s.handler = nil - return - } - - s.api = api - s.handler = configureAPI(api) -} - -func (s *Server) hasScheme(scheme string) bool { - schemes := s.EnabledListeners - if len(schemes) == 0 { - schemes = defaultSchemes - } - - for _, v := range schemes { - if v == scheme { - return true - } - } - return false -} - -// Serve the api -func (s *Server) Serve() (err error) { - if !s.hasListeners { - if err = s.Listen(); err != nil { - return err - } - } - - // set default handler, if none is set - if s.handler == nil { - if s.api == nil { - return errors.New("can't create the default handler, as no api is set") - } - - s.SetHandler(s.api.Serve(nil)) - } - - wg := new(sync.WaitGroup) - once := new(sync.Once) - signalNotify(s.interrupt) - go handleInterrupt(once, s) - - servers := []*http.Server{} - - if s.hasScheme(schemeUnix) { - domainSocket := new(http.Server) - domainSocket.MaxHeaderBytes = int(s.MaxHeaderSize) - domainSocket.Handler = s.handler - if int64(s.CleanupTimeout) > 0 { - domainSocket.IdleTimeout = s.CleanupTimeout - } - - configureServer(domainSocket, "unix", string(s.SocketPath)) - - servers = append(servers, domainSocket) - wg.Add(1) - s.Logf("Serving fulcio server at unix://%s", s.SocketPath) - go func(l net.Listener) { - defer wg.Done() - if err := domainSocket.Serve(l); err != nil && err != http.ErrServerClosed { - s.Fatalf("%v", err) - } - s.Logf("Stopped serving fulcio server at unix://%s", s.SocketPath) - }(s.domainSocketL) - } - - if s.hasScheme(schemeHTTP) { - httpServer := new(http.Server) - httpServer.MaxHeaderBytes = int(s.MaxHeaderSize) - httpServer.ReadTimeout = s.ReadTimeout - httpServer.WriteTimeout = s.WriteTimeout - httpServer.SetKeepAlivesEnabled(int64(s.KeepAlive) > 0) - if s.ListenLimit > 0 { - s.httpServerL = netutil.LimitListener(s.httpServerL, s.ListenLimit) - } - - if int64(s.CleanupTimeout) > 0 { - httpServer.IdleTimeout = s.CleanupTimeout - } - - httpServer.Handler = s.handler - - configureServer(httpServer, "http", s.httpServerL.Addr().String()) - - servers = append(servers, httpServer) - wg.Add(1) - s.Logf("Serving fulcio server at http://%s", s.httpServerL.Addr()) - go func(l net.Listener) { - defer wg.Done() - if err := httpServer.Serve(l); err != nil && err != http.ErrServerClosed { - s.Fatalf("%v", err) - } - s.Logf("Stopped serving fulcio server at http://%s", l.Addr()) - }(s.httpServerL) - } - - if s.hasScheme(schemeHTTPS) { - httpsServer := new(http.Server) - httpsServer.MaxHeaderBytes = int(s.MaxHeaderSize) - httpsServer.ReadTimeout = s.TLSReadTimeout - httpsServer.WriteTimeout = s.TLSWriteTimeout - httpsServer.SetKeepAlivesEnabled(int64(s.TLSKeepAlive) > 0) - if s.TLSListenLimit > 0 { - s.httpsServerL = netutil.LimitListener(s.httpsServerL, s.TLSListenLimit) - } - if int64(s.CleanupTimeout) > 0 { - httpsServer.IdleTimeout = s.CleanupTimeout - } - httpsServer.Handler = s.handler - - // Inspired by https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go - httpsServer.TLSConfig = &tls.Config{ - // Causes servers to use Go's default ciphersuite preferences, - // which are tuned to avoid attacks. Does nothing on clients. - PreferServerCipherSuites: true, - // Only use curves which have assembly implementations - // https://github.com/golang/go/tree/master/src/crypto/elliptic - CurvePreferences: []tls.CurveID{tls.CurveP256}, - // Use modern tls mode https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility - NextProtos: []string{"h2", "http/1.1"}, - // https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Protocols - MinVersion: tls.VersionTLS12, - // These ciphersuites support Forward Secrecy: https://en.wikipedia.org/wiki/Forward_secrecy - CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - }, - } - - // build standard config from server options - if s.TLSCertificate != "" && s.TLSCertificateKey != "" { - httpsServer.TLSConfig.Certificates = make([]tls.Certificate, 1) - httpsServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(s.TLSCertificate, s.TLSCertificateKey) - if err != nil { - return err - } - } - - if s.TLSCACertificate != "" { - // include specified CA certificate - caCert, caCertErr := ioutil.ReadFile(s.TLSCACertificate) - if caCertErr != nil { - return caCertErr - } - caCertPool := x509.NewCertPool() - ok := caCertPool.AppendCertsFromPEM(caCert) - if !ok { - return fmt.Errorf("cannot parse CA certificate") - } - httpsServer.TLSConfig.ClientCAs = caCertPool - httpsServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert - } - - // call custom TLS configurator - configureTLS(httpsServer.TLSConfig) - - if len(httpsServer.TLSConfig.Certificates) == 0 && httpsServer.TLSConfig.GetCertificate == nil { - // after standard and custom config are passed, this ends up with no certificate - if s.TLSCertificate == "" { - if s.TLSCertificateKey == "" { - s.Fatalf("the required flags `--tls-certificate` and `--tls-key` were not specified") - } - s.Fatalf("the required flag `--tls-certificate` was not specified") - } - if s.TLSCertificateKey == "" { - s.Fatalf("the required flag `--tls-key` was not specified") - } - // this happens with a wrong custom TLS configurator - s.Fatalf("no certificate was configured for TLS") - } - - configureServer(httpsServer, "https", s.httpsServerL.Addr().String()) - - servers = append(servers, httpsServer) - wg.Add(1) - s.Logf("Serving fulcio server at https://%s", s.httpsServerL.Addr()) - go func(l net.Listener) { - defer wg.Done() - if err := httpsServer.Serve(l); err != nil && err != http.ErrServerClosed { - s.Fatalf("%v", err) - } - s.Logf("Stopped serving fulcio server at https://%s", l.Addr()) - }(tls.NewListener(s.httpsServerL, httpsServer.TLSConfig)) - } - - wg.Add(1) - go s.handleShutdown(wg, &servers) - - wg.Wait() - return nil -} - -// Listen creates the listeners for the server -func (s *Server) Listen() error { - if s.hasListeners { // already done this - return nil - } - - if s.hasScheme(schemeHTTPS) { - // Use http host if https host wasn't defined - if s.TLSHost == "" { - s.TLSHost = s.Host - } - // Use http listen limit if https listen limit wasn't defined - if s.TLSListenLimit == 0 { - s.TLSListenLimit = s.ListenLimit - } - // Use http tcp keep alive if https tcp keep alive wasn't defined - if int64(s.TLSKeepAlive) == 0 { - s.TLSKeepAlive = s.KeepAlive - } - // Use http read timeout if https read timeout wasn't defined - if int64(s.TLSReadTimeout) == 0 { - s.TLSReadTimeout = s.ReadTimeout - } - // Use http write timeout if https write timeout wasn't defined - if int64(s.TLSWriteTimeout) == 0 { - s.TLSWriteTimeout = s.WriteTimeout - } - } - - if s.hasScheme(schemeUnix) { - domSockListener, err := net.Listen("unix", string(s.SocketPath)) - if err != nil { - return err - } - s.domainSocketL = domSockListener - } - - if s.hasScheme(schemeHTTP) { - listener, err := net.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port))) - if err != nil { - return err - } - - h, p, err := swag.SplitHostPort(listener.Addr().String()) - if err != nil { - return err - } - s.Host = h - s.Port = p - s.httpServerL = listener - } - - if s.hasScheme(schemeHTTPS) { - tlsListener, err := net.Listen("tcp", net.JoinHostPort(s.TLSHost, strconv.Itoa(s.TLSPort))) - if err != nil { - return err - } - - sh, sp, err := swag.SplitHostPort(tlsListener.Addr().String()) - if err != nil { - return err - } - s.TLSHost = sh - s.TLSPort = sp - s.httpsServerL = tlsListener - } - - s.hasListeners = true - return nil -} - -// Shutdown server and clean up resources -func (s *Server) Shutdown() error { - if atomic.CompareAndSwapInt32(&s.shuttingDown, 0, 1) { - close(s.shutdown) - } - return nil -} - -func (s *Server) handleShutdown(wg *sync.WaitGroup, serversPtr *[]*http.Server) { - // wg.Done must occur last, after s.api.ServerShutdown() - // (to preserve old behaviour) - defer wg.Done() - - <-s.shutdown - - servers := *serversPtr - - ctx, cancel := context.WithTimeout(context.TODO(), s.GracefulTimeout) - defer cancel() - - // first execute the pre-shutdown hook - s.api.PreServerShutdown() - - shutdownChan := make(chan bool) - for i := range servers { - server := servers[i] - go func() { - var success bool - defer func() { - shutdownChan <- success - }() - if err := server.Shutdown(ctx); err != nil { - // Error from closing listeners, or context timeout: - s.Logf("HTTP server Shutdown: %v", err) - } else { - success = true - } - }() - } - - // Wait until all listeners have successfully shut down before calling ServerShutdown - success := true - for range servers { - success = success && <-shutdownChan - } - if success { - s.api.ServerShutdown() - } -} - -// GetHandler returns a handler useful for testing -func (s *Server) GetHandler() http.Handler { - return s.handler -} - -// SetHandler allows for setting a http handler on this server -func (s *Server) SetHandler(handler http.Handler) { - s.handler = handler -} - -// UnixListener returns the domain socket listener -func (s *Server) UnixListener() (net.Listener, error) { - if !s.hasListeners { - if err := s.Listen(); err != nil { - return nil, err - } - } - return s.domainSocketL, nil -} - -// HTTPListener returns the http listener -func (s *Server) HTTPListener() (net.Listener, error) { - if !s.hasListeners { - if err := s.Listen(); err != nil { - return nil, err - } - } - return s.httpServerL, nil -} - -// TLSListener returns the https listener -func (s *Server) TLSListener() (net.Listener, error) { - if !s.hasListeners { - if err := s.Listen(); err != nil { - return nil, err - } - } - return s.httpsServerL, nil -} - -func handleInterrupt(once *sync.Once, s *Server) { - once.Do(func() { - for range s.interrupt { - if s.interrupted { - s.Logf("Server already shutting down") - continue - } - s.interrupted = true - s.Logf("Shutting down... ") - if err := s.Shutdown(); err != nil { - s.Logf("HTTP server Shutdown: %v", err) - } - } - }) -} - -func signalNotify(interrupt chan<- os.Signal) { - signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) -}