Compare commits

..

No commits in common. "main" and "0.3.0" have entirely different histories.
main ... 0.3.0

24 changed files with 253 additions and 278 deletions

View file

@ -8,7 +8,7 @@ linters-settings:
const: const:
ORGANIZATION: CAcert Inc. ORGANIZATION: CAcert Inc.
template: |- template: |-
Copyright {{ ORGANIZATION }} Copyright {{ YEAR-RANGE }} {{ ORGANIZATION }}
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -47,7 +47,7 @@ linters:
- gofmt - gofmt
- goheader - goheader
- goimports - goimports
- mnd - gomnd
- gosec - gosec
- lll - lll
- makezero - makezero

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -23,7 +23,6 @@ import (
"crypto/x509" "crypto/x509"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"os" "os"
"time" "time"
@ -31,6 +30,7 @@ import (
"github.com/knadh/koanf" "github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/toml" "github.com/knadh/koanf/parsers/toml"
"github.com/knadh/koanf/providers/confmap" "github.com/knadh/koanf/providers/confmap"
log "github.com/sirupsen/logrus"
"code.cacert.org/cacert/oidc-demo-app/ui" "code.cacert.org/cacert/oidc-demo-app/ui"
@ -84,59 +84,45 @@ func (f *StaticFileInfoWrapper) ModTime() time.Time {
return f.fixedModTime return f.fixedModTime
} }
func main() { //nolint:cyclop func main() {
var ( logger := log.New()
logLevel = new(slog.LevelVar)
logHandler slog.Handler config, err := services.ConfigureApplication(
logger *slog.Logger logger,
"RESOURCE_APP",
services.DefaultConfiguration,
) )
logHandler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})
logger = slog.New(logHandler)
slog.SetDefault(logger)
config, err := services.ConfigureApplication("RESOURCE_APP", services.DefaultConfiguration)
if err != nil { if err != nil {
logger.Error("error loading configuration", "error", err) log.Fatalf("error loading configuration: %v", err)
os.Exit(1)
} }
if level := config.Bytes("log.level"); level != nil {
if err := logLevel.UnmarshalText(level); err != nil {
logger.Error("could not parse log level", "error", err)
os.Exit(1)
}
slog.SetLogLoggerLevel(logLevel.Level())
}
if config.Bool("log.json") {
logHandler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})
logger = slog.New(logHandler)
slog.SetDefault(logger)
}
logLogger := slog.NewLogLogger(logger.Handler(), logLevel.Level())
oidcServer := config.MustString("oidc.server") oidcServer := config.MustString("oidc.server")
oidcClientID := config.MustString("oidc.client-id") oidcClientID := config.MustString("oidc.client-id")
oidcClientSecret := config.MustString("oidc.client-secret") oidcClientSecret := config.MustString("oidc.client-secret")
logger.Info( if level := config.String("log.level"); level != "" {
"Starting CAcert OpenID Connect demo application", logLevel, err := log.ParseLevel(level)
"version", version, "commit", commit, "date", date, if err != nil {
) logger.WithError(err).Fatal("could not parse log level")
logger.Info("Server is starting") }
logger.SetLevel(logLevel)
}
if config.Bool("log.json") {
logger.SetFormatter(&log.JSONFormatter{})
}
logger.WithFields(log.Fields{
"version": version, "commit": commit, "date": date,
}).Info("Starting CAcert OpenID Connect demo application")
logger.Infoln("Server is starting")
bundle, catalog := services.InitI18n(logger, config.Strings("i18n.languages")) bundle, catalog := services.InitI18n(logger, config.Strings("i18n.languages"))
services.AddMessages(catalog) services.AddMessages(catalog)
tlsClientConfig, err := getTLSConfig(config) tlsClientConfig := getTLSConfig(config)
if err != nil {
logger.Error("error loading tls config", "error", err)
os.Exit(1)
}
apiTransport := &http.Transport{TLSClientConfig: tlsClientConfig} apiTransport := &http.Transport{TLSClientConfig: tlsClientConfig}
apiClient := &http.Client{Transport: apiTransport} apiClient := &http.Client{Transport: apiTransport}
@ -148,53 +134,37 @@ func main() { //nolint:cyclop
APIClient: apiClient, APIClient: apiClient,
}) })
if err != nil { if err != nil {
logger.Error("OpenID Connect discovery failed", "error", err) logger.WithError(err).Fatal("OpenID Connect discovery failed")
os.Exit(1)
} }
sessionPath, sessionAuthKey, sessionEncKey, err := configureSessionParameters(logger, config) sessionPath, sessionAuthKey, sessionEncKey := configureSessionParameters(config)
if err != nil { services.InitSessionStore(logger, sessionPath, sessionAuthKey, sessionEncKey)
logger.Error("error configuring session parameters", "error", err)
os.Exit(1)
}
if err := services.InitSessionStore(sessionPath, sessionAuthKey, sessionEncKey); err != nil { authMiddleware := handlers.Authenticate(oidcInfo.OAuth2Config)
logger.Error("could not initialize session store", "error", err)
os.Exit(1)
}
authMiddleware := handlers.Authenticate(logger, oidcInfo.OAuth2Config)
publicURL := buildPublicURL(config.MustString("server.name"), config.MustInt("server.port")) publicURL := buildPublicURL(config.MustString("server.name"), config.MustInt("server.port"))
tokenInfoService, err := services.InitTokenInfoService(logger, oidcInfo) tokenInfoService, err := services.InitTokenInfoService(logger, oidcInfo)
if err != nil { if err != nil {
logger.Error("could not initialize token info service", "error", err) logger.WithError(err).Fatal("could not initialize token info service")
os.Exit(1)
} }
indexHandler, err := handlers.NewIndexHandler(logger, bundle, catalog, oidcInfo, publicURL, tokenInfoService) indexHandler, err := handlers.NewIndexHandler(logger, bundle, catalog, oidcInfo, publicURL, tokenInfoService)
if err != nil { if err != nil {
logger.Error("could not initialize index handler", "error", err) logger.WithError(err).Fatal("could not initialize index handler")
os.Exit(1)
} }
protectedResource, err := handlers.NewProtectedResourceHandler( protectedResource, err := handlers.NewProtectedResourceHandler(
logger, bundle, catalog, oidcInfo, publicURL, tokenInfoService, logger, bundle, catalog, oidcInfo, publicURL, tokenInfoService,
) )
if err != nil { if err != nil {
logger.Error("could not initialize protected resource handler", "error", err) logger.WithError(err).Fatal("could not initialize protected resource handler")
} }
callbackHandler := handlers.NewCallbackHandler(logger, oidcInfo.KeySet, oidcInfo.OAuth2Config) callbackHandler := handlers.NewCallbackHandler(logger, oidcInfo.KeySet, oidcInfo.OAuth2Config)
afterLogoutHandler := handlers.NewAfterLogoutHandler(logger) afterLogoutHandler := handlers.NewAfterLogoutHandler(logger)
staticFiles, err := staticFileHandler() staticFiles := staticFileHandler(logger)
if err != nil {
logger.Error("could not initialize static file handler", "error", err)
os.Exit(1)
}
router := http.NewServeMux() router := http.NewServeMux()
router.Handle("/", indexHandler) router.Handle("/", indexHandler)
@ -212,13 +182,12 @@ func main() { //nolint:cyclop
} }
tracing := handlers.Tracing(nextRequestID) tracing := handlers.Tracing(nextRequestID)
logging := handlers.Logging(logLogger) logging := handlers.Logging(logger)
hsts := handlers.EnableHSTS() hsts := handlers.EnableHSTS()
errorMiddleware, err := handlers.ErrorHandling(logger, bundle, catalog) errorMiddleware, err := handlers.ErrorHandling(logger, bundle, catalog)
if err != nil { if err != nil {
logger.Error("could not initialize request error handling", "error", err) logger.WithError(err).Fatal("could not initialize request error handling")
os.Exit(1)
} }
tlsConfig := &tls.Config{ tlsConfig := &tls.Config{
@ -235,16 +204,13 @@ func main() { //nolint:cyclop
TLSConfig: tlsConfig, TLSConfig: tlsConfig,
} }
if err := handlers.StartApplication(context.Background(), logger, server, publicURL, config); err != nil { handlers.StartApplication(context.Background(), logger, server, publicURL, config)
logger.Error("could not start application", "error", err)
os.Exit(1)
}
} }
func staticFileHandler() (func(w http.ResponseWriter, r *http.Request), error) { func staticFileHandler(logger *log.Logger) func(w http.ResponseWriter, r *http.Request) {
stat, err := os.Stat(os.Args[0]) stat, err := os.Stat(os.Args[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not use stat on binary: %w", err) logger.WithError(err).Fatal("could not use stat on binary")
} }
fileServer := http.FileServer(&StaticFSWrapper{FileSystem: http.FS(ui.Static), ModTime: stat.ModTime()}) fileServer := http.FileServer(&StaticFSWrapper{FileSystem: http.FS(ui.Static), ModTime: stat.ModTime()})
@ -257,10 +223,10 @@ func staticFileHandler() (func(w http.ResponseWriter, r *http.Request), error) {
fileServer.ServeHTTP(w, r) fileServer.ServeHTTP(w, r)
} }
return staticFiles, nil return staticFiles
} }
func getTLSConfig(config *koanf.Koanf) (*tls.Config, error) { func getTLSConfig(config *koanf.Koanf) *tls.Config {
tlsClientConfig := &tls.Config{ tlsClientConfig := &tls.Config{
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
} }
@ -271,14 +237,14 @@ func getTLSConfig(config *koanf.Koanf) (*tls.Config, error) {
pemBytes, err := os.ReadFile(rootCAFile) pemBytes, err := os.ReadFile(rootCAFile)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not read CA certificate file: %w", err) log.Fatalf("could not read CA certificate file: %v", err)
} }
caCertPool.AppendCertsFromPEM(pemBytes) caCertPool.AppendCertsFromPEM(pemBytes)
tlsClientConfig.RootCAs = caCertPool tlsClientConfig.RootCAs = caCertPool
} }
return tlsClientConfig, nil return tlsClientConfig
} }
func buildPublicURL(hostname string, port int) string { func buildPublicURL(hostname string, port int) string {
@ -291,36 +257,28 @@ func buildPublicURL(hostname string, port int) string {
return fmt.Sprintf("https://%s", hostname) return fmt.Sprintf("https://%s", hostname)
} }
func configureSessionParameters(logger *slog.Logger, config *koanf.Koanf) (string, []byte, []byte, error) { func configureSessionParameters(config *koanf.Koanf) (string, []byte, []byte) {
sessionPath := config.MustString("session.path") sessionPath := config.MustString("session.path")
sessionAuthKey, err := base64.StdEncoding.DecodeString(config.String("session.auth-key")) sessionAuthKey, err := base64.StdEncoding.DecodeString(config.String("session.auth-key"))
if err != nil { if err != nil {
return "", nil, nil, fmt.Errorf("could not decode session authentication key: %w", err) log.WithError(err).Fatal("could not decode session auth key")
} }
sessionEncKey, err := base64.StdEncoding.DecodeString(config.String("session.enc-key")) sessionEncKey, err := base64.StdEncoding.DecodeString(config.String("session.enc-key"))
if err != nil { if err != nil {
return "", nil, nil, fmt.Errorf("could not decode session encryption key: %w", err) log.WithError(err).Fatal("could not decode session encryption key")
} }
generated := false generated := false
if len(sessionAuthKey) != sessionAuthKeyLength { if len(sessionAuthKey) != sessionAuthKeyLength {
sessionAuthKey, err = services.GenerateKey(sessionAuthKeyLength) sessionAuthKey = services.GenerateKey(sessionAuthKeyLength)
if err != nil {
return "", nil, nil, fmt.Errorf("could not generate session authentication key: %w", err)
}
generated = true generated = true
} }
if len(sessionEncKey) != sessionKeyLength { if len(sessionEncKey) != sessionKeyLength {
sessionEncKey, err = services.GenerateKey(sessionKeyLength) sessionEncKey = services.GenerateKey(sessionKeyLength)
if err != nil {
return "", nil, nil, fmt.Errorf("could not generate session encryption key: %w", err)
}
generated = true generated = true
} }
@ -332,12 +290,11 @@ func configureSessionParameters(logger *slog.Logger, config *koanf.Koanf) (strin
tomlData, err := config.Marshal(toml.Parser()) tomlData, err := config.Marshal(toml.Parser())
if err != nil { if err != nil {
return "", nil, nil, fmt.Errorf("could not encode session configuration: %w", err) log.WithError(err).Fatal("could not encode session config")
} }
logger.Info("put the following in your resource_app.toml") log.Infof("put the following in your resource_app.toml:\n%s", string(tomlData))
fmt.Print(string(tomlData)) //nolint:forbidigo
} }
return sessionPath, sessionAuthKey, sessionEncKey, nil return sessionPath, sessionAuthKey, sessionEncKey
} }

29
go.mod
View file

@ -1,25 +1,27 @@
module code.cacert.org/cacert/oidc-demo-app module code.cacert.org/cacert/oidc-demo-app
go 1.22 go 1.19
require ( require (
github.com/BurntSushi/toml v1.3.2 github.com/BurntSushi/toml v1.3.2
github.com/gorilla/sessions v1.2.2 github.com/gorilla/sessions v1.2.1
github.com/knadh/koanf v1.5.0 github.com/knadh/koanf v1.5.0
github.com/lestrrat-go/jwx v1.2.29 github.com/lestrrat-go/jwx v1.2.26
github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/nicksnyder/go-i18n/v2 v2.2.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
golang.org/x/oauth2 v0.20.0 golang.org/x/oauth2 v0.10.0
golang.org/x/text v0.15.0 golang.org/x/text v0.11.0
) )
require ( require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-json v0.10.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect github.com/lestrrat-go/option v1.0.1 // indirect
@ -28,6 +30,9 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
golang.org/x/crypto v0.23.0 // indirect golang.org/x/crypto v0.11.0 // indirect
golang.org/x/sys v0.20.0 // indirect golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
) )

74
go.sum
View file

@ -1,6 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -38,9 +39,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -51,8 +51,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -84,6 +84,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -96,15 +98,12 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
@ -166,14 +165,14 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0=
github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ=
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
@ -210,8 +209,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA=
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0=
github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@ -252,13 +251,14 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -267,9 +267,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
@ -286,10 +285,9 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -308,6 +306,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/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-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -321,12 +320,13 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -370,19 +370,17 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -390,11 +388,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -415,6 +413,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
@ -440,6 +440,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -18,18 +18,19 @@ limitations under the License.
package handlers package handlers
import ( import (
"log/slog"
"net/http" "net/http"
"github.com/sirupsen/logrus"
) )
type AfterLogoutHandler struct { type AfterLogoutHandler struct {
logger *slog.Logger logger *logrus.Logger
} }
func (h *AfterLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *AfterLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
session, err := GetSession(r) session, err := GetSession(r)
if err != nil { if err != nil {
h.logger.Error("could not get session", "error", err) h.logger.WithError(err).Error("could not get session")
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
@ -38,13 +39,13 @@ func (h *AfterLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
session.Options.MaxAge = -1 session.Options.MaxAge = -1
if err = session.Save(r, w); err != nil { if err = session.Save(r, w); err != nil {
h.logger.Error("could not save session", "error", err) h.logger.WithError(err).Error("could not save session")
} }
w.Header().Set("Location", "/") w.Header().Set("Location", "/")
w.WriteHeader(http.StatusFound) w.WriteHeader(http.StatusFound)
} }
func NewAfterLogoutHandler(logger *slog.Logger) *AfterLogoutHandler { func NewAfterLogoutHandler(logger *logrus.Logger) *AfterLogoutHandler {
return &AfterLogoutHandler{logger: logger} return &AfterLogoutHandler{logger: logger}
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,7 +20,6 @@ package handlers
import ( import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
@ -35,13 +34,12 @@ const (
sessionName = "resource_app" sessionName = "resource_app"
) )
func Authenticate(logger *slog.Logger, oauth2Config *oauth2.Config) func(http.Handler) http.Handler { func Authenticate(oauth2Config *oauth2.Config) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session, err := GetSession(r) session, err := GetSession(r)
if err != nil { if err != nil {
logger.ErrorContext(r.Context(), "failed to get session", "error", err) http.Error(w, err.Error(), http.StatusInternalServerError)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
@ -55,21 +53,14 @@ func Authenticate(logger *slog.Logger, oauth2Config *oauth2.Config) func(http.Ha
session.Values[services.SessionRedirectTarget] = r.URL.String() session.Values[services.SessionRedirectTarget] = r.URL.String()
if err = session.Save(r, w); err != nil { if err = session.Save(r, w); err != nil {
logger.ErrorContext(r.Context(), "failed to save session", "error", err) http.Error(w, err.Error(), http.StatusInternalServerError)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
state, err := services.GenerateKey(oauth2RedirectStateLength) authURL := oauth2Config.AuthCodeURL(
if err != nil { base64.URLEncoding.EncodeToString(services.GenerateKey(oauth2RedirectStateLength)),
logger.ErrorContext( )
r.Context(), "failed to generate state for starting OIDC flow", "error", err,
)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
authURL := oauth2Config.AuthCodeURL(base64.URLEncoding.EncodeToString(state))
w.Header().Set("Location", authURL) w.Header().Set("Location", authURL)
w.WriteHeader(http.StatusFound) w.WriteHeader(http.StatusFound)
@ -77,9 +68,28 @@ func Authenticate(logger *slog.Logger, oauth2Config *oauth2.Config) func(http.Ha
} }
} }
/*
func getRequestedClaims(logger *log.Logger) string {
claims := make(models.OIDCClaimsRequest)
claims["userinfo"] = make(models.ClaimElement)
essentialItem := make(models.IndividualClaimRequest)
essentialItem["essential"] = true
claims["userinfo"]["https://auth.cacert.org/groups"] = &essentialItem
target := make([]byte, 0)
buf := bytes.NewBuffer(target)
enc := json.NewEncoder(buf)
if err := enc.Encode(claims); err != nil {
logger.WithError(err).Warn("could not encode claims request parameter")
}
return buf.String()
}
*/
func GetSession(r *http.Request) (*sessions.Session, error) { func GetSession(r *http.Request) (*sessions.Session, error) {
session, err := services.GetSessionStore().Get(r, sessionName) session, err := services.GetSessionStore().Get(r, sessionName)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get session") return nil, fmt.Errorf("could not get session")
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -21,10 +21,10 @@ import (
"context" "context"
"fmt" "fmt"
"html/template" "html/template"
"log/slog"
"net/http" "net/http"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
log "github.com/sirupsen/logrus"
"code.cacert.org/cacert/oidc-demo-app/ui" "code.cacert.org/cacert/oidc-demo-app/ui"
@ -47,7 +47,7 @@ type ErrorDetails struct {
type ErrorBucket struct { type ErrorBucket struct {
errorDetails *ErrorDetails errorDetails *ErrorDetails
templates *template.Template templates *template.Template
logger *slog.Logger logger *log.Logger
bundle *i18n.Bundle bundle *i18n.Bundle
messageCatalog *services.MessageCatalog messageCatalog *services.MessageCatalog
} }
@ -74,7 +74,7 @@ func (b *ErrorBucket) serveHTTP(w http.ResponseWriter, r *http.Request) {
err := b.templates.Lookup("base").Execute(w, data) err := b.templates.Lookup("base").Execute(w, data)
if err != nil { if err != nil {
b.logger.Error("error rendering error template", "error", err) log.WithError(err).Error("error rendering error template")
http.Error( http.Error(
w, w,
http.StatusText(http.StatusInternalServerError), http.StatusText(http.StatusInternalServerError),
@ -143,7 +143,7 @@ func (w *errorResponseWriter) Write(content []byte) (int, error) {
} }
func ErrorHandling( func ErrorHandling(
logger *slog.Logger, logger *log.Logger,
bundle *i18n.Bundle, bundle *i18n.Bundle,
messageCatalog *services.MessageCatalog, messageCatalog *services.MessageCatalog,
) (func(http.Handler) http.Handler, error) { ) (func(http.Handler) http.Handler, error) {

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,11 +20,11 @@ package handlers
import ( import (
"fmt" "fmt"
"html/template" "html/template"
"log/slog"
"net/http" "net/http"
"net/url" "net/url"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
log "github.com/sirupsen/logrus"
"code.cacert.org/cacert/oidc-demo-app/ui" "code.cacert.org/cacert/oidc-demo-app/ui"
@ -34,7 +34,7 @@ import (
type IndexHandler struct { type IndexHandler struct {
bundle *i18n.Bundle bundle *i18n.Bundle
indexTemplate *template.Template indexTemplate *template.Template
logger *slog.Logger logger *log.Logger
logoutURL string logoutURL string
messageCatalog *services.MessageCatalog messageCatalog *services.MessageCatalog
publicURL string publicURL string
@ -80,7 +80,7 @@ func (h *IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tokenInfo, err := h.tokenInfo.GetTokenInfo(session) tokenInfo, err := h.tokenInfo.GetTokenInfo(session)
if err != nil { if err != nil {
h.logger.Error("failed to get token info for request", "error", err) h.logger.WithError(err).Error("failed to get token info for request")
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
@ -88,7 +88,7 @@ func (h *IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
if !tokenInfo.Expires.IsZero() { if !tokenInfo.Expires.IsZero() {
h.logger.Info("id token expires at", "expires", tokenInfo.Expires) h.logger.WithField("expires", tokenInfo.Expires).Info("id token expires at")
} }
w.Header().Add("Content-Type", "text/html") w.Header().Add("Content-Type", "text/html")
@ -130,7 +130,7 @@ func (h *IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
func NewIndexHandler( func NewIndexHandler(
logger *slog.Logger, logger *log.Logger,
bundle *i18n.Bundle, bundle *i18n.Bundle,
catalog *services.MessageCatalog, catalog *services.MessageCatalog,
oidcInfo *services.OIDCInformation, oidcInfo *services.OIDCInformation,

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,9 +20,10 @@ package handlers
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"net/http" "net/http"
"sync/atomic" "sync/atomic"
log "github.com/sirupsen/logrus"
) )
type key int type key int
@ -63,7 +64,7 @@ func Logging(logger *log.Logger) func(http.Handler) http.Handler {
requestID = "unknown" requestID = "unknown"
} }
logger.Printf( logger.Infof(
"[%s] %s \"%s %s\" %d %d \"%s\"", "[%s] %s \"%s %s\" %d %d \"%s\"",
requestID, requestID,
r.RemoteAddr, r.RemoteAddr,
@ -96,7 +97,7 @@ func Tracing(nextRequestID func() string) func(http.Handler) http.Handler {
var Healthy int32 var Healthy int32
func NewHealthHandler() http.Handler { func NewHealthHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if atomic.LoadInt32(&Healthy) == 1 { if atomic.LoadInt32(&Healthy) == 1 {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -19,12 +19,12 @@ package handlers
import ( import (
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"time" "time"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/lestrrat-go/jwx/jwk" "github.com/lestrrat-go/jwx/jwk"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"code.cacert.org/cacert/oidc-demo-app/internal/services" "code.cacert.org/cacert/oidc-demo-app/internal/services"
@ -32,7 +32,7 @@ import (
type OidcCallbackHandler struct { type OidcCallbackHandler struct {
keySet jwk.Set keySet jwk.Set
logger *slog.Logger logger *log.Logger
oauth2Config *oauth2.Config oauth2Config *oauth2.Config
} }
@ -59,7 +59,7 @@ func (c *OidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
tok, err := c.oauth2Config.Exchange(r.Context(), code) tok, err := c.oauth2Config.Exchange(r.Context(), code)
if err != nil { if err != nil {
c.logger.Error("could not perform token exchange", "error", err) c.logger.WithError(err).Error("could not perform token exchange")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
@ -67,14 +67,14 @@ func (c *OidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
session, err := GetSession(r) session, err := GetSession(r)
if err != nil { if err != nil {
c.logger.Error("could not get session", "error", err) c.logger.WithError(err).Error("could not get session")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
if err = c.storeTokens(session, tok); err != nil { if err = c.storeTokens(session, tok); err != nil {
c.logger.Error("could not store token in session", "error", err) c.logger.WithError(err).Error("could not store token in session")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -82,7 +82,7 @@ func (c *OidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }
if err = session.Save(r, w); err != nil { if err = session.Save(r, w); err != nil {
c.logger.Error("could not save session", "error", err) c.logger.WithError(err).Error("could not save session")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -143,20 +143,19 @@ func (c *OidcCallbackHandler) storeTokens(
return fmt.Errorf("could not parse ID token: %w", err) return fmt.Errorf("could not parse ID token: %w", err)
} }
c.logger.Debug( c.logger.WithFields(log.Fields{
"receive OpenID Connect ID Token", "sub": oidcToken.Subject(),
"sub", oidcToken.Subject(), "aud": oidcToken.Audience(),
"aud", oidcToken.Audience(), "issued_at": oidcToken.IssuedAt(),
"issued_at", oidcToken.IssuedAt(), "iss": oidcToken.Issuer(),
"iss", oidcToken.Issuer(), "not_before": oidcToken.NotBefore(),
"not_before", oidcToken.NotBefore(), "exp": oidcToken.Expiration(),
"exp", oidcToken.Expiration(), }).Debug("receive OpenID Connect ID Token")
)
return nil return nil
} }
func NewCallbackHandler(logger *slog.Logger, keySet jwk.Set, oauth2Config *oauth2.Config) *OidcCallbackHandler { func NewCallbackHandler(logger *log.Logger, keySet jwk.Set, oauth2Config *oauth2.Config) *OidcCallbackHandler {
return &OidcCallbackHandler{ return &OidcCallbackHandler{
keySet: keySet, keySet: keySet,
logger: logger, logger: logger,

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,11 +20,11 @@ package handlers
import ( import (
"fmt" "fmt"
"html/template" "html/template"
"log/slog"
"net/http" "net/http"
"net/url" "net/url"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
log "github.com/sirupsen/logrus"
"code.cacert.org/cacert/oidc-demo-app/internal/services" "code.cacert.org/cacert/oidc-demo-app/internal/services"
"code.cacert.org/cacert/oidc-demo-app/ui" "code.cacert.org/cacert/oidc-demo-app/ui"
@ -32,7 +32,7 @@ import (
type ProtectedResource struct { type ProtectedResource struct {
bundle *i18n.Bundle bundle *i18n.Bundle
logger *slog.Logger logger *log.Logger
protectedTemplate *template.Template protectedTemplate *template.Template
logoutURL string logoutURL string
tokenInfo *services.TokenInfoService tokenInfo *services.TokenInfoService
@ -79,7 +79,7 @@ func (h *ProtectedResource) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tokenInfo, err := h.tokenInfo.GetTokenInfo(session) tokenInfo, err := h.tokenInfo.GetTokenInfo(session)
if err != nil { if err != nil {
h.logger.Error("failed to get token info for request", "error", err) h.logger.WithError(err).Error("failed to get token info for request")
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
@ -87,7 +87,7 @@ func (h *ProtectedResource) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
if !tokenInfo.Expires.IsZero() { if !tokenInfo.Expires.IsZero() {
h.logger.Info("id token expires at", "expires", tokenInfo.Expires) h.logger.WithField("expires", tokenInfo.Expires).Info("id token expires at")
} }
if tokenInfo.IDToken == "" { if tokenInfo.IDToken == "" {
@ -130,7 +130,7 @@ func (h *ProtectedResource) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
func NewProtectedResourceHandler( func NewProtectedResourceHandler(
logger *slog.Logger, logger *log.Logger,
bundle *i18n.Bundle, bundle *i18n.Bundle,
catalog *services.MessageCatalog, catalog *services.MessageCatalog,
oidcInfo *services.OIDCInformation, oidcInfo *services.OIDCInformation,

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,8 +20,6 @@ package handlers
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"log/slog"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
@ -29,18 +27,23 @@ import (
"time" "time"
"github.com/knadh/koanf" "github.com/knadh/koanf"
"github.com/sirupsen/logrus"
) )
func StartApplication( func StartApplication(
ctx context.Context, logger *slog.Logger, server *http.Server, publicURL string, config *koanf.Koanf, ctx context.Context,
) error { logger *logrus.Logger,
server *http.Server,
publicURL string,
config *koanf.Koanf,
) {
done := make(chan bool) done := make(chan bool)
quit := make(chan os.Signal, 1) quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt) signal.Notify(quit, os.Interrupt)
go func() { go func() {
<-quit <-quit
logger.Info("Server is shutting down...") logger.Infoln("Server is shutting down...")
atomic.StoreInt32(&Healthy, 0) atomic.StoreInt32(&Healthy, 0)
const shutdownWaitTime = 30 * time.Second const shutdownWaitTime = 30 * time.Second
@ -52,25 +55,24 @@ func StartApplication(
server.SetKeepAlivesEnabled(false) server.SetKeepAlivesEnabled(false)
if err := server.Shutdown(ctx); err != nil { if err := server.Shutdown(ctx); err != nil {
logger.Error("Could not gracefully shutdown the server", "error", err) logger.WithError(err).Fatal("Could not gracefully shutdown the server")
} }
close(done) close(done)
}() }()
logger.Info("Server is ready to handle requests", "public_url", publicURL) logger.WithField("public_url", publicURL).Info("Server is ready to handle requests")
atomic.StoreInt32(&Healthy, 1) atomic.StoreInt32(&Healthy, 1)
if err := server.ListenAndServeTLS( if err := server.ListenAndServeTLS(
config.String("server.certificate"), config.String("server.key"), config.String("server.certificate"), config.String("server.key"),
); err != nil && !errors.Is(err, http.ErrServerClosed) { ); err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Error("Could not listen on requested address", "server_address", server.Addr) logger.WithError(err).WithField(
"server_address",
return fmt.Errorf("listening failed: %w", err) server.Addr,
).Fatal("Could not listen on requested address")
} }
<-done <-done
logger.Info("Server stopped") logger.Infoln("Server stopped")
return nil
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,6 @@ package services
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"strings" "strings"
@ -29,6 +28,7 @@ import (
"github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/providers/posflag" "github.com/knadh/koanf/providers/posflag"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
@ -51,12 +51,13 @@ var DefaultConfiguration = map[string]interface{}{
} }
func ConfigureApplication( func ConfigureApplication(
logger *logrus.Logger,
appName string, appName string,
defaultConfig map[string]interface{}, defaultConfig map[string]interface{},
) (*koanf.Koanf, error) { ) (*koanf.Koanf, error) {
f := pflag.NewFlagSet("config", pflag.ContinueOnError) f := pflag.NewFlagSet("config", pflag.ContinueOnError)
f.Usage = func() { f.Usage = func() {
log.Print(f.FlagUsages()) logger.Info(f.FlagUsages())
os.Exit(0) os.Exit(0)
} }
@ -69,7 +70,7 @@ func ConfigureApplication(
var err error var err error
if err = f.Parse(os.Args[1:]); err != nil { if err = f.Parse(os.Args[1:]); err != nil {
return nil, fmt.Errorf("could not parse command line arguments: %w", err) logger.WithError(err).Fatal("could not parse command line arguments")
} }
config := koanf.New(".") config := koanf.New(".")
@ -77,18 +78,18 @@ func ConfigureApplication(
_ = config.Load(confmap.Provider(defaultConfig, "."), nil) _ = config.Load(confmap.Provider(defaultConfig, "."), nil)
if err = config.Load(file.Provider(defaultFile), toml.Parser()); err != nil && !os.IsNotExist(err) { if err = config.Load(file.Provider(defaultFile), toml.Parser()); err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("could not load configuration from file %s: %w", defaultFile, err) logrus.WithError(err).WithField("file", defaultFile).Fatal("error loading configuration from file")
} }
cFiles, _ := f.GetStringSlice("conf") cFiles, _ := f.GetStringSlice("conf")
for _, c := range cFiles { for _, c := range cFiles {
if err = config.Load(file.Provider(c), toml.Parser()); err != nil { if err = config.Load(file.Provider(c), toml.Parser()); err != nil {
return nil, fmt.Errorf("error loading configuration from file %s: %w", c, err) logger.WithError(err).WithField("file", c).Fatal("error loading configuration from file")
} }
} }
if err = config.Load(posflag.Provider(f, ".", config), nil); err != nil { if err = config.Load(posflag.Provider(f, ".", config), nil); err != nil {
return nil, fmt.Errorf("error loading configuration from command line: %w", err) logger.WithError(err).Fatal("error loading configuration from command line")
} }
prefix := fmt.Sprintf("%s_", strings.ToUpper(appName)) prefix := fmt.Sprintf("%s_", strings.ToUpper(appName))
@ -96,7 +97,7 @@ func ConfigureApplication(
if err = config.Load(env.Provider(prefix, ".", func(s string) string { if err = config.Load(env.Provider(prefix, ".", func(s string) string {
return strings.ReplaceAll(strings.ToLower(strings.TrimPrefix(s, prefix)), "_", ".") return strings.ReplaceAll(strings.ToLower(strings.TrimPrefix(s, prefix)), "_", ".")
}), nil); err != nil { }), nil); err != nil {
return nil, fmt.Errorf("error loading configuration from environment variables: %w", err) logrus.WithError(err).Fatal("error loading configuration from environment")
} }
return config, nil return config, nil

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,7 +20,6 @@ package services
import ( import (
"errors" "errors"
"fmt" "fmt"
"log/slog"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language" "golang.org/x/text/language"
@ -28,6 +27,7 @@ import (
"code.cacert.org/cacert/oidc-demo-app/translations" "code.cacert.org/cacert/oidc-demo-app/translations"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
log "github.com/sirupsen/logrus"
) )
func AddMessages(catalog *MessageCatalog) { func AddMessages(catalog *MessageCatalog) {
@ -83,7 +83,7 @@ func AddMessages(catalog *MessageCatalog) {
type MessageCatalog struct { type MessageCatalog struct {
messages map[string]*i18n.Message messages map[string]*i18n.Message
logger *slog.Logger logger *log.Logger
} }
func (m *MessageCatalog) AddMessages(messages map[string]*i18n.Message) { func (m *MessageCatalog) AddMessages(messages map[string]*i18n.Message) {
@ -102,11 +102,11 @@ func (m *MessageCatalog) LookupErrorMessage(
message, ok := m.messages[fieldTag] message, ok := m.messages[fieldTag]
if !ok { if !ok {
m.logger.Info("no specific error message for field and tag", "field_tag", fieldTag) m.logger.WithField("field_tag", fieldTag).Info("no specific error message for field and tag")
message, ok = m.messages[tag] message, ok = m.messages[tag]
if !ok { if !ok {
m.logger.Info("no specific error message for tag", "tag", tag) m.logger.WithField("tag", tag).Info("no specific error message for tag")
message, ok = m.messages["unknown"] message, ok = m.messages["unknown"]
if !ok { if !ok {
@ -124,7 +124,7 @@ func (m *MessageCatalog) LookupErrorMessage(
}, },
}) })
if err != nil { if err != nil {
m.logger.Error("localization failed", "error", err) m.logger.WithError(err).Error("localization failed")
return tag return tag
} }
@ -149,7 +149,7 @@ func (m *MessageCatalog) LookupMessage(
return translation return translation
} }
m.logger.Warn("no translation found for id", "id", id) m.logger.WithField("id", id).Warn("no translation found for id")
return id return id
} }
@ -158,19 +158,19 @@ func (m *MessageCatalog) handleLocalizeError(id string, translation string, err
var messageNotFound *i18n.MessageNotFoundErr var messageNotFound *i18n.MessageNotFoundErr
if errors.As(err, &messageNotFound) { if errors.As(err, &messageNotFound) {
m.logger.Warn("message not found", "error", err, "message", id) m.logger.WithError(err).WithField("message", id).Warn("message not found")
if translation != "" { if translation != "" {
return translation return translation
} }
} else { } else {
m.logger.Error("translation error", "error", err, "message", id) m.logger.WithError(err).WithField("message", id).Error("translation error")
} }
return id return id
} }
func InitI18n(logger *slog.Logger, languages []string) (*i18n.Bundle, *MessageCatalog) { func InitI18n(logger *log.Logger, languages []string) (*i18n.Bundle, *MessageCatalog) {
bundle := i18n.NewBundle(language.English) bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
@ -179,7 +179,7 @@ func InitI18n(logger *slog.Logger, languages []string) (*i18n.Bundle, *MessageCa
bundleBytes, err := translations.Bundles.ReadFile(bundleName) bundleBytes, err := translations.Bundles.ReadFile(bundleName)
if err != nil { if err != nil {
logger.Warn("message bundle not found", "bundle", bundleName) logger.WithField("bundle", bundleName).Warn("message bundle not found")
continue continue
} }
@ -192,7 +192,7 @@ func InitI18n(logger *slog.Logger, languages []string) (*i18n.Bundle, *MessageCa
return bundle, catalog return bundle, catalog
} }
func initMessageCatalog(logger *slog.Logger) *MessageCatalog { func initMessageCatalog(logger *log.Logger) *MessageCatalog {
messages := make(map[string]*i18n.Message) messages := make(map[string]*i18n.Message)
messages["ErrorTitle"] = &i18n.Message{ messages["ErrorTitle"] = &i18n.Message{
ID: "ErrorTitle", ID: "ErrorTitle",

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -22,12 +22,12 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
"github.com/lestrrat-go/jwx/jwk" "github.com/lestrrat-go/jwx/jwk"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"code.cacert.org/cacert/oidc-demo-app/internal/models" "code.cacert.org/cacert/oidc-demo-app/internal/models"
@ -57,19 +57,17 @@ type OIDCInformation struct {
// retrieved by GetOAuth2Config. // retrieved by GetOAuth2Config.
// //
// The JSON Web Key Set can be retrieved by GetJwkSet. // The JSON Web Key Set can be retrieved by GetJwkSet.
func DiscoverOIDC(logger *slog.Logger, params *OidcParams) (*OIDCInformation, error) { func DiscoverOIDC(logger *log.Logger, params *OidcParams) (*OIDCInformation, error) {
discoveryURL, err := url.Parse(params.OidcServer) discoveryURL, err := url.Parse(params.OidcServer)
if err != nil { if err != nil {
logger.Error( logger.WithError(err).WithField(
"could not parse parameter oidc.server as URL", "oidc.server",
"oidc.server", params.OidcServer, params.OidcServer,
) ).Fatal("could not parse parameter value")
} else {
return nil, fmt.Errorf("could not parse parameter value: %w", err) discoveryURL.Path = "/.well-known/openid-configuration"
} }
discoveryURL.Path = "/.well-known/openid-configuration"
var ( var (
body []byte body []byte
req *http.Request req *http.Request

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -19,20 +19,21 @@ package services
import ( import (
"crypto/rand" "crypto/rand"
"fmt"
log "github.com/sirupsen/logrus"
) )
func GenerateKey(length int) ([]byte, error) { func GenerateKey(length int) []byte {
key := make([]byte, length) key := make([]byte, length)
read, err := rand.Read(key) read, err := rand.Read(key)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not generate key: %w", err) log.WithError(err).Fatal("could not generate key")
} }
if read != length { if read != length {
return nil, fmt.Errorf("read unexpected number of bytes, read %d, expected %d", read, length) log.WithFields(log.Fields{"read": read, "expected": length}).Fatal("read unexpected number of bytes")
} }
return key, nil return key
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -18,10 +18,10 @@ limitations under the License.
package services package services
import ( import (
"fmt"
"os" "os"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
log "github.com/sirupsen/logrus"
) )
var store *sessions.FilesystemStore var store *sessions.FilesystemStore
@ -33,18 +33,16 @@ const (
SessionRedirectTarget SessionRedirectTarget
) )
func InitSessionStore(sessionPath string, keys ...[]byte) error { func InitSessionStore(logger *log.Logger, sessionPath string, keys ...[]byte) {
store = sessions.NewFilesystemStore(sessionPath, keys...) store = sessions.NewFilesystemStore(sessionPath, keys...)
if _, err := os.Stat(sessionPath); err != nil { if _, err := os.Stat(sessionPath); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
if err = os.MkdirAll(sessionPath, 0700); err != nil { //nolint:mnd if err = os.MkdirAll(sessionPath, 0700); err != nil { //nolint:gomnd
return fmt.Errorf("could not create session store director: %w", err) logger.WithError(err).Fatal("could not create session store director")
} }
} }
} }
return nil
} }
func GetSessionStore() *sessions.FilesystemStore { func GetSessionStore() *sessions.FilesystemStore {

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -20,13 +20,13 @@ package services
import ( import (
"errors" "errors"
"fmt" "fmt"
"log/slog"
"time" "time"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/lestrrat-go/jwx/jwk" "github.com/lestrrat-go/jwx/jwk"
"github.com/lestrrat-go/jwx/jwt" "github.com/lestrrat-go/jwx/jwt"
"github.com/lestrrat-go/jwx/jwt/openid" "github.com/lestrrat-go/jwx/jwt/openid"
log "github.com/sirupsen/logrus"
) )
type OIDCTokenInfo struct { type OIDCTokenInfo struct {
@ -39,7 +39,7 @@ type OIDCTokenInfo struct {
} }
type TokenInfoService struct { type TokenInfoService struct {
logger *slog.Logger logger *log.Logger
keySet jwk.Set keySet jwk.Set
} }
@ -49,15 +49,15 @@ func (s *TokenInfoService) GetTokenInfo(session *sessions.Session) (*OIDCTokenIn
var ok bool var ok bool
if tokenInfo.AccessToken, ok = session.Values[SessionAccessToken].(string); ok { if tokenInfo.AccessToken, ok = session.Values[SessionAccessToken].(string); ok {
s.logger.Debug("found access token in session", "access_token", tokenInfo.AccessToken) s.logger.WithField("access_token", tokenInfo.AccessToken).Debug("found access token in session")
} }
if tokenInfo.RefreshToken, ok = session.Values[SessionRefreshToken].(string); ok { if tokenInfo.RefreshToken, ok = session.Values[SessionRefreshToken].(string); ok {
s.logger.Debug("found refresh token in session", "refresh_token", tokenInfo.RefreshToken) s.logger.WithField("refresh_token", tokenInfo.RefreshToken).Debug("found refresh token in session")
} }
if tokenInfo.IDToken, ok = session.Values[SessionIDToken].(string); ok { if tokenInfo.IDToken, ok = session.Values[SessionIDToken].(string); ok {
s.logger.Debug("found ID token in session", "id_token", tokenInfo.IDToken) s.logger.WithField("id_token", tokenInfo.IDToken).Debug("found ID token in session")
} }
if tokenInfo.IDToken == "" { if tokenInfo.IDToken == "" {
@ -78,7 +78,7 @@ func (s *TokenInfoService) GetTokenInfo(session *sessions.Session) (*OIDCTokenIn
return tokenInfo, nil return tokenInfo, nil
} }
func InitTokenInfoService(logger *slog.Logger, oidcInfo *OIDCInformation) (*TokenInfoService, error) { func InitTokenInfoService(logger *log.Logger, oidcInfo *OIDCInformation) (*TokenInfoService, error) {
return &TokenInfoService{logger: logger, keySet: oidcInfo.KeySet}, nil return &TokenInfoService{logger: logger, keySet: oidcInfo.KeySet}, nil
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

View file

@ -41,7 +41,7 @@
{{ template "content" . }} {{ template "content" . }}
<footer class="footer mt-auto py-3"> <footer class="footer mt-auto py-3">
<div class="container"> <div class="container">
<span class="text-muted small">© <a href="https://www.cacert.org/">CAcert</a></span> <span class="text-muted small">© 2020-2023 <a href="https://www.cacert.org/">CAcert</a></span>
</div> </div>
</footer> </footer>
<script type="text/javascript" src="/js/cacert.bundle.js"></script> <script type="text/javascript" src="/js/cacert.bundle.js"></script>

View file

@ -1,5 +1,5 @@
/* /*
Copyright CAcert Inc. Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");