From 7d17a1bd802c904f90ab6bef79d10fd187d50d26 Mon Sep 17 00:00:00 2001 From: Simon Gottschlag Date: Thu, 7 Oct 2021 11:07:13 +0200 Subject: [PATCH 1/5] remove claimsClient --- pkg/claims/claims.go | 94 ------------------ pkg/claims/claims_test.go | 178 ---------------------------------- pkg/handlers/handlers.go | 13 +-- pkg/handlers/handlers_test.go | 98 ++----------------- pkg/proxy/proxy.go | 6 +- 5 files changed, 10 insertions(+), 379 deletions(-) delete mode 100644 pkg/claims/claims.go delete mode 100644 pkg/claims/claims_test.go diff --git a/pkg/claims/claims.go b/pkg/claims/claims.go deleted file mode 100644 index 6672c77c..00000000 --- a/pkg/claims/claims.go +++ /dev/null @@ -1,94 +0,0 @@ -package claims - -import ( - "context" - "errors" - "fmt" - - "github.com/coreos/go-oidc" - "github.com/go-logr/logr" -) - -// ClaimNames contains the _claim_names struct -type ClaimNames struct { - Groups string `json:"groups"` -} - -// ClaimSourcesSource contains the src1 struct -// TODO: Could there be something else than Endpoint? -type ClaimSourcesSource struct { - Endpoint string `json:"endpoint"` -} - -// ClaimSources contains _claim_sources struct -// TODO: Could there be more than one source? -type ClaimSources struct { - Source1 ClaimSourcesSource `json:"src1"` -} - -// AzureClaims contains the Azure AD v2 token claims -type AzureClaims struct { - Audience string `json:"aud"` - Issuer string `json:"iss"` - IssuedAt int64 `json:"iat"` - NotBefore int64 `json:"nbf"` - ExpirationTime int64 `json:"exp"` - ClaimNames ClaimNames `json:"_claim_names"` - ClaimSources ClaimSources `json:"_claim_sources"` - Subject string `json:"sub"` - TokenVersion string `json:"ver"` - TenantID string `json:"tid"` - ApplicationID string `json:"azp"` - ObjectID string `json:"oid"` - Username string `json:"preferred_username"` - Groups []string `json:"groups"` -} - -// ClientInterface ... -type ClientInterface interface { - NewClaims(t *oidc.IDToken) (AzureClaims, error) - GetOIDCVerifier(ctx context.Context, tenantID, clientID string) (*oidc.IDTokenVerifier, error) -} - -// Client ... -type Client struct{} - -// NewClaimsClient ... -func NewClaimsClient() ClientInterface { - return &Client{} -} - -// NewClaims returns AzureClaims -func (client *Client) NewClaims(t *oidc.IDToken) (AzureClaims, error) { - var c AzureClaims - - if t == nil { - return AzureClaims{}, errors.New("Token nil") - } - - err := t.Claims(&c) - if err != nil { - return AzureClaims{}, err - } - - return c, nil -} - -// GetOIDCVerifier returns an ID Token Verifier or an error -func (client *Client) GetOIDCVerifier(ctx context.Context, tenantID, clientID string) (*oidc.IDTokenVerifier, error) { - log := logr.FromContextOrDiscard(ctx) - issuerURL := fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", tenantID) - provider, err := oidc.NewProvider(ctx, issuerURL) - if err != nil { - log.Error(err, "Unable to initiate OIDC provider") - return nil, err - } - - oidcConfig := &oidc.Config{ - ClientID: clientID, - } - - verifier := provider.Verifier(oidcConfig) - - return verifier, nil -} diff --git a/pkg/claims/claims_test.go b/pkg/claims/claims_test.go deleted file mode 100644 index 08ffbbec..00000000 --- a/pkg/claims/claims_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package claims - -import ( - "context" - "encoding/json" - "fmt" - "io" - "os" - "strings" - "testing" - "time" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" - "github.com/coreos/go-oidc" - "github.com/go-logr/logr" -) - -func TestNewClaims(t *testing.T) { - clientID := getEnvOrSkip(t, "CLIENT_ID") - tenantID := getEnvOrSkip(t, "TENANT_ID") - spClientID := getEnvOrSkip(t, "TEST_USER_SP_CLIENT_ID") - spClientSecret := getEnvOrSkip(t, "TEST_USER_SP_CLIENT_SECRET") - spResource := getEnvOrSkip(t, "TEST_USER_SP_RESOURCE") - ctx := logr.NewContext(context.Background(), logr.Discard()) - claimsClient := NewClaimsClient() - - verifier, err := claimsClient.GetOIDCVerifier(ctx, tenantID, clientID) - if err != nil { - t.Errorf("Expected err to be nil but it was %q", err) - } - - token, err := getAccessToken(ctx, tenantID, spClientID, spClientSecret, fmt.Sprintf("%s/.default", spResource)) - if err != nil { - t.Errorf("Expected err to be nil but it was %q", err) - } - - verifiedToken, err := verifier.Verify(ctx, token.Token) - if err != nil { - t.Errorf("Expected err to be nil but it was %q", err) - } - - claims, err := claimsClient.NewClaims(verifiedToken) - if err != nil { - t.Errorf("Expected err to be nil but it was %q", err) - } - - if claims.ApplicationID != spClientID { - t.Errorf("Returned ApplicationID wasn't what was expected.\nExpected: %s\nActual: %s", spClientID, spClientID) - } - - _, err = claimsClient.NewClaims(nil) - if !strings.Contains(err.Error(), "Token nil") { - t.Errorf("Expected err to contain 'Token nil': %q", err) - } - - _, err = claimsClient.NewClaims(&oidc.IDToken{}) - if !strings.Contains(err.Error(), "oidc: claims not set") { - t.Errorf("Expected err to contain 'oidc: claims not set': %q", err) - } -} - -func TestGetOIDCVerifier(t *testing.T) { - clientID := getEnvOrSkip(t, "CLIENT_ID") - tenantID := getEnvOrSkip(t, "TENANT_ID") - ctx := logr.NewContext(context.Background(), logr.Discard()) - claimsClient := NewClaimsClient() - - cases := []struct { - tenantID string - clientID string - expectedErrContains string - }{ - { - tenantID: tenantID, - clientID: clientID, - expectedErrContains: "", - }, - { - tenantID: "", - clientID: "", - expectedErrContains: "AADSTS90002", - }, - } - - for _, c := range cases { - _, err := claimsClient.GetOIDCVerifier(ctx, c.tenantID, c.clientID) - if err != nil && len(c.expectedErrContains) == 0 { - t.Errorf("Expected err to be nil but it was %q", err) - } - - if len(c.expectedErrContains) > 0 { - if !strings.Contains(err.Error(), c.expectedErrContains) { - t.Errorf("Expected err to contain %q but it was %q", c.expectedErrContains, err) - } - } - } -} - -func getEnvOrSkip(t *testing.T, envVar string) string { - v := os.Getenv(envVar) - if v == "" { - t.Skipf("%s environment variable is empty, skipping.", envVar) - } - - return v -} - -func getAccessToken(ctx context.Context, tenantID, clientID, clientSecret, scope string) (*azcore.AccessToken, error) { - tokenFilePath := fmt.Sprintf("../../tmp/test-token-file_%s", clientID) - tokenFileExists := fileExists(tokenFilePath) - token := &azcore.AccessToken{} - - generateNewToken := true - if tokenFileExists { - fileContent, err := getFileContent(tokenFilePath) - if err != nil { - return nil, err - } - - err = json.Unmarshal(fileContent, &token) - if err != nil { - return nil, err - } - - if token.ExpiresOn.After(time.Now().Add(-5 * time.Minute)) { - generateNewToken = false - } - } - - if generateNewToken { - cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, clientSecret, nil) - if err != nil { - return nil, err - } - - token, err := cred.GetToken(ctx, azpolicy.TokenRequestOptions{Scopes: []string{scope}}) - if err != nil { - return nil, err - } - - fileContents, err := json.Marshal(&token) - if err != nil { - return nil, err - } - - err = os.WriteFile(tokenFilePath, fileContents, 0644) - if err != nil { - return nil, err - } - - return token, nil - } - - return token, nil -} - -func fileExists(s string) bool { - _, err := os.Stat(s) - return err == nil -} - -func getFileContent(s string) ([]byte, error) { - file, err := os.Open(s) - if err != nil { - return nil, err - } - - defer file.Close() - - bytes, err := io.ReadAll(file) - if err != nil { - return nil, err - } - - return bytes, nil -} diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index 2bc7c55e..5ab11b9d 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -8,10 +8,8 @@ import ( "net/http/httputil" "strings" - "github.com/coreos/go-oidc" "github.com/go-logr/logr" "github.com/xenitab/azad-kube-proxy/pkg/cache" - "github.com/xenitab/azad-kube-proxy/pkg/claims" "github.com/xenitab/azad-kube-proxy/pkg/config" "github.com/xenitab/azad-kube-proxy/pkg/health" "github.com/xenitab/azad-kube-proxy/pkg/models" @@ -38,25 +36,16 @@ type ClientInterface interface { type Client struct { Config config.Config CacheClient cache.ClientInterface - OIDCVerifier *oidc.IDTokenVerifier UserClient user.ClientInterface - ClaimsClient claims.ClientInterface HealthClient health.ClientInterface } // NewHandlersClient ... -func NewHandlersClient(ctx context.Context, config config.Config, cacheClient cache.ClientInterface, userClient user.ClientInterface, claimsClient claims.ClientInterface, healthClient health.ClientInterface) (ClientInterface, error) { - oidcVerifier, err := claimsClient.GetOIDCVerifier(ctx, config.TenantID, config.ClientID) - if err != nil { - return nil, err - } - +func NewHandlersClient(ctx context.Context, config config.Config, cacheClient cache.ClientInterface, userClient user.ClientInterface, healthClient health.ClientInterface) (ClientInterface, error) { handlersClient := &Client{ Config: config, CacheClient: cacheClient, - OIDCVerifier: oidcVerifier, UserClient: userClient, - ClaimsClient: claimsClient, HealthClient: healthClient, } diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go index e64e9588..0a0d99b5 100644 --- a/pkg/handlers/handlers_test.go +++ b/pkg/handlers/handlers_test.go @@ -18,11 +18,9 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore" azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" - "github.com/coreos/go-oidc" "github.com/go-logr/logr" "github.com/gorilla/mux" "github.com/xenitab/azad-kube-proxy/pkg/cache" - "github.com/xenitab/azad-kube-proxy/pkg/claims" "github.com/xenitab/azad-kube-proxy/pkg/config" "github.com/xenitab/azad-kube-proxy/pkg/health" "github.com/xenitab/azad-kube-proxy/pkg/models" @@ -36,7 +34,6 @@ var ( func TestNewHandlersClient(t *testing.T) { tenantID := getEnvOrSkip(t, "TENANT_ID") ctx := logr.NewContext(context.Background(), logr.Discard()) - fakeClaimsClient := newFakeClaimsClient(nil, nil, claims.AzureClaims{}, &oidc.IDTokenVerifier{}) fakeCacheClient := newFakeCacheClient("", "", nil, false, nil) fakeUserClient := newFakeUserClient("", "", nil, nil) fakeHealthClient := newFakeHealthClient(true, nil, true, nil) @@ -52,13 +49,12 @@ func TestNewHandlersClient(t *testing.T) { }, } - _, err = NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, fakeClaimsClient, fakeHealthClient) + _, err = NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, fakeHealthClient) if err != nil { t.Errorf("Expected err to be nil but it was %q", err) } - fakeClaimsClient = newFakeClaimsClient(nil, errors.New("fake error"), claims.AzureClaims{}, &oidc.IDTokenVerifier{}) - _, err = NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, fakeClaimsClient, fakeHealthClient) + _, err = NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, fakeHealthClient) if !strings.Contains(err.Error(), "fake error") { t.Errorf("Expected err to contain 'fake error' but it was %q", err) } @@ -87,7 +83,6 @@ func TestReadinessHandler(t *testing.T) { fakeCacheClient := newFakeCacheClient("", "", nil, true, nil) fakeUserClient := newFakeUserClient("", "", nil, nil) - claimsClient := claims.NewClaimsClient() cases := []struct { healthClient health.ClientInterface @@ -107,7 +102,7 @@ func TestReadinessHandler(t *testing.T) { } for _, c := range cases { - proxyHandlers, err := NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, claimsClient, c.healthClient) + proxyHandlers, err := NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, c.healthClient) if err != nil { t.Errorf("Expected err to be nil but it was %q", err) } @@ -153,7 +148,6 @@ func TestLivenessHandler(t *testing.T) { fakeCacheClient := newFakeCacheClient("", "", nil, true, nil) fakeUserClient := newFakeUserClient("", "", nil, nil) - claimsClient := claims.NewClaimsClient() cases := []struct { healthClient health.ClientInterface @@ -173,7 +167,7 @@ func TestLivenessHandler(t *testing.T) { } for _, c := range cases { - proxyHandlers, err := NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, claimsClient, c.healthClient) + proxyHandlers, err := NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, c.healthClient) if err != nil { t.Errorf("Expected err to be nil but it was %q", err) } @@ -215,7 +209,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { if err != nil { t.Errorf("Expected err to be nil but it was %q", err) } - claimsClient := claims.NewClaimsClient() fakeCacheClient := newFakeCacheClient("", "", nil, false, nil) fakeUserClient := newFakeUserClient("", "", nil, nil) fakeHealthClient := newFakeHealthClient(true, nil, true, nil) @@ -248,8 +241,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { configFunction func(oldConfig config.Config) config.Config cacheClient cache.ClientInterface cacheFunction func(oldCacheClient cache.ClientInterface) cache.ClientInterface - claimsClient claims.ClientInterface - claimsFunction func(oldClaimsClient claims.ClientInterface) claims.ClientInterface userClient user.ClientInterface userFunction func(oldUserClient user.ClientInterface) user.ClientInterface expectedResCode int @@ -267,7 +258,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: memCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusOK, expectedErrContains: "", @@ -284,7 +274,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: memCacheClient, - claimsClient: claimsClient, expectedResCode: http.StatusForbidden, expectedErrContains: "Unable to extract Bearer token", }, @@ -300,7 +289,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: memCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusUnauthorized, expectedErrContains: "Unable to verify token", @@ -317,7 +305,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusOK, expectedErrContains: "", @@ -334,7 +321,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusUnauthorized, expectedErrContains: "Unable to verify token", @@ -351,7 +337,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: newFakeCacheClient("", "", nil, true, errors.New("Fake error")), - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusInternalServerError, expectedErrContains: "Unexpected error", @@ -369,7 +354,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusForbidden, expectedErrContains: "User unauthorized", @@ -387,7 +371,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusForbidden, expectedErrContains: "User unauthorized", @@ -406,7 +389,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusForbidden, expectedErrContains: "User unauthorized", @@ -425,7 +407,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusForbidden, expectedErrContains: "User unauthorized", @@ -442,7 +423,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: newFakeClaimsClient(errors.New("fake error"), nil, claims.AzureClaims{}, nil), userClient: fakeUserClient, expectedResCode: http.StatusForbidden, expectedErrContains: "Unable to get claims", @@ -459,7 +439,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, config: cfg, cacheClient: fakeCacheClient, - claimsClient: claimsClient, userClient: newFakeUserClient("", "", nil, errors.New("fake error")), expectedResCode: http.StatusForbidden, expectedErrContains: "Unable to get user", @@ -474,10 +453,9 @@ func TestAzadKubeProxyHandler(t *testing.T) { "Authorization": {fmt.Sprintf("Bearer %s", token.Token)}, }, }, - config: cfg, - cacheClient: fakeCacheClient, - claimsClient: claimsClient, - userClient: fakeUserClient, + config: cfg, + cacheClient: fakeCacheClient, + userClient: fakeUserClient, userFunction: func(oldUserClient user.ClientInterface) user.ClientInterface { i := 1 groups := []models.Group{} @@ -509,7 +487,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { return oldConfig }, cacheClient: memCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusOK, expectedErrContains: "", @@ -530,7 +507,6 @@ func TestAzadKubeProxyHandler(t *testing.T) { return oldConfig }, cacheClient: memCacheClient, - claimsClient: claimsClient, userClient: fakeUserClient, expectedResCode: http.StatusInternalServerError, expectedErrContains: "Unexpected error", @@ -546,15 +522,11 @@ func TestAzadKubeProxyHandler(t *testing.T) { c.cacheClient = c.cacheFunction(c.cacheClient) } - if c.claimsFunction != nil { - c.claimsClient = c.claimsFunction(c.claimsClient) - } - if c.userFunction != nil { c.userClient = c.userFunction(c.userClient) } - proxyHandlers, err := NewHandlersClient(ctx, c.config, c.cacheClient, c.userClient, c.claimsClient, fakeHealthClient) + proxyHandlers, err := NewHandlersClient(ctx, c.config, c.cacheClient, c.userClient, fakeHealthClient) if err != nil { t.Errorf("Expected err to be nil but it was %q", err) } @@ -664,38 +636,6 @@ func (c *fakeCacheClient) SetGroup(ctx context.Context, s string, g models.Group return c.fakeError } -type fakeClaimsClient struct { - fakeAzureClaims claims.AzureClaims - fakeOIDCVerifier *oidc.IDTokenVerifier - newClaimsFakeError error - getOIDCVerifierFakeError error -} - -func newFakeClaimsClient(newClaimsFakeError error, getOIDCVerifierFakeError error, fakeAzureClaims claims.AzureClaims, fakeOIDCVerifier *oidc.IDTokenVerifier) *fakeClaimsClient { - return &fakeClaimsClient{ - fakeAzureClaims: fakeAzureClaims, - fakeOIDCVerifier: fakeOIDCVerifier, - newClaimsFakeError: newClaimsFakeError, - getOIDCVerifierFakeError: getOIDCVerifierFakeError, - } -} - -func (client *fakeClaimsClient) NewClaims(t *oidc.IDToken) (claims.AzureClaims, error) { - if client.newClaimsFakeError != nil { - return claims.AzureClaims{}, client.newClaimsFakeError - } - if client.fakeAzureClaims.Issuer == "" { - realClaimsClient := claims.NewClaimsClient() - realClaims, err := realClaimsClient.NewClaims(t) - if err != nil { - return claims.AzureClaims{}, err - } - return realClaims, nil - } - - return client.fakeAzureClaims, client.newClaimsFakeError -} - type fakeHealthClient struct { ready bool readyError error @@ -720,28 +660,6 @@ func (client *fakeHealthClient) Live(ctx context.Context) (bool, error) { return client.live, client.liveError } -func (client *fakeClaimsClient) GetOIDCVerifier(ctx context.Context, tenantID, clientID string) (*oidc.IDTokenVerifier, error) { - if client.getOIDCVerifierFakeError != nil { - return nil, client.getOIDCVerifierFakeError - } - - log := logr.FromContextOrDiscard(ctx) - issuerURL := fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", tenantID) - provider, err := oidc.NewProvider(ctx, issuerURL) - if err != nil { - log.Error(err, "Unable to initiate OIDC provider") - return nil, err - } - - oidcConfig := &oidc.Config{ - ClientID: clientID, - } - - verifier := provider.Verifier(oidcConfig) - - return verifier, nil -} - func getEnvOrSkip(t *testing.T, envVar string) string { v := os.Getenv(envVar) if v == "" { diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index d8a7d830..29241173 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -16,7 +16,6 @@ import ( "github.com/gorilla/mux" "github.com/xenitab/azad-kube-proxy/pkg/azure" "github.com/xenitab/azad-kube-proxy/pkg/cache" - "github.com/xenitab/azad-kube-proxy/pkg/claims" "github.com/xenitab/azad-kube-proxy/pkg/config" "github.com/xenitab/azad-kube-proxy/pkg/cors" "github.com/xenitab/azad-kube-proxy/pkg/dashboard" @@ -42,7 +41,6 @@ type Client struct { CacheClient cache.ClientInterface UserClient user.ClientInterface AzureClient azure.ClientInterface - ClaimsClient claims.ClientInterface DashboardClient dashboard.ClientInterface MetricsClient metrics.ClientInterface HealthClient health.ClientInterface @@ -62,7 +60,6 @@ func NewProxyClient(ctx context.Context, config config.Config) (ClientInterface, } userClient := user.NewUserClient(config, azureClient) - claimsClient := claims.NewClaimsClient() dashboardClient, err := dashboard.NewDashboardClient(ctx, config) if err != nil { @@ -86,7 +83,6 @@ func NewProxyClient(ctx context.Context, config config.Config) (ClientInterface, CacheClient: cacheClient, UserClient: userClient, AzureClient: azureClient, - ClaimsClient: claimsClient, DashboardClient: dashboardClient, MetricsClient: metricsClient, HealthClient: healthClient, @@ -122,7 +118,7 @@ func (client *Client) Start(ctx context.Context) error { defer stopGroupSync() // Configure reverse proxy and http server - proxyHandlers, err := handlers.NewHandlersClient(ctx, client.Config, client.CacheClient, client.UserClient, client.ClaimsClient, client.HealthClient) + proxyHandlers, err := handlers.NewHandlersClient(ctx, client.Config, client.CacheClient, client.UserClient, client.HealthClient) if err != nil { return err } From bcf5bde83bab6741c161d9347b8900043f091347 Mon Sep 17 00:00:00 2001 From: Simon Gottschlag Date: Thu, 7 Oct 2021 11:07:22 +0200 Subject: [PATCH 2/5] add oidcHandler --- go.mod | 12 ++++ go.sum | 146 +++++++++++++++++++++++++++++++++++++++ pkg/handlers/handlers.go | 92 ++++++++++++++++++------ pkg/proxy/proxy.go | 15 +++- 4 files changed, 243 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index f513eae4..95001e99 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/rs/cors v1.8.0 github.com/sirupsen/logrus v1.8.1 github.com/urfave/cli/v2 v2.3.0 + github.com/xenitab/go-oidc-middleware v0.0.14 go.uber.org/zap v1.19.1 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/sync v0.0.0-20210220032951-036812b2e83c @@ -37,15 +38,18 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.1 // indirect github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect + github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/evanphx/json-patch v4.11.0+incompatible // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/goccy/go-json v0.7.8 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -57,6 +61,12 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc // indirect github.com/leodido/go-urn v1.2.1 // indirect + github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect + github.com/lestrrat-go/blackmagic v1.0.0 // indirect + github.com/lestrrat-go/httpcc v1.0.0 // indirect + github.com/lestrrat-go/iter v1.0.1 // indirect + github.com/lestrrat-go/jwx v1.2.7 // indirect + github.com/lestrrat-go/option v1.0.0 // indirect github.com/lunixbochs/vtclean v1.0.0 // indirect github.com/mattn/go-colorable v0.1.11 // indirect github.com/mattn/go-isatty v0.0.14 // indirect @@ -73,8 +83,10 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 // indirect + github.com/zclconf/go-cty v1.9.1 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect + go.uber.org/ratelimit v0.2.0 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 // indirect golang.org/x/sys v0.0.0-20211003122950-b1ebd4e1001c // indirect diff --git a/go.sum b/go.sum index a3769da4..c2c9947a 100644 --- a/go.sum +++ b/go.sum @@ -46,10 +46,12 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= 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= @@ -59,6 +61,11 @@ github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZp github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.15.1 h1:Fw+ixAJPmKhCLBqDwHlTDqxUxp0xjEwXczEpt1B6r7k= github.com/alicebob/miniredis/v2 v2.15.1/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -86,9 +93,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cristalhq/aconfig v0.16.2/go.mod h1:NXaRp+1e6bkO4dJn+wZ71xyaihMDYPtCSvEhMTm/H3E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0/go.mod h1:J70FGZSbzsjecRTiTzER+3f1KZLNaXkuv+yeFTKoxM8= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= @@ -102,13 +117,19 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= 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/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/go-chi/chi/v5 v5.0.4 h1:5e494iHzsYBiyXQAHHuI4tyJS9M3V84OuX3ufIIGHFo= +github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -126,26 +147,38 @@ github.com/go-logr/logr v1.1.0 h1:nAbevmWlS2Ic4m4+/An5NXkaGqlqpbBgdcuThZxnZyI= github.com/go-logr/logr v1.1.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.1.0 h1:rZHor2gcVGCG11UlKl+WUsfCMOOi2k/mTCDKDK6zZws= github.com/go-logr/zapr v1.1.0/go.mod h1:YShqdLLTU346TNVu8Tvwe3bOo6gc75oZ1joeE+1lYdQ= +github.com/go-oauth2/oauth2/v4 v4.3.0 h1:vp4goUmrq1YaPzpm34FDLlZiAkIqK3LsuNTTRyTnPbo= +github.com/go-oauth2/oauth2/v4 v4.3.0/go.mod h1:+rsyi0o/ZbSfhL/3Xr/sAtL4brS+IdGj86PHVlPjE+4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A= github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8= github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc= +github.com/go-session/session v3.1.2+incompatible h1:yStchEObKg4nk2F7JGE7KoFIrA/1Y078peagMWcrncg= +github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.7.8 h1:CvMH7LotYymYuLGEohBM1lTZWX4g6jzWUUl2aLFuBoE= +github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gofiber/fiber/v2 v2.19.0/go.mod h1:/LdZHMUXZvTTo7gU4+b1hclqCAdoQphNQ9bi9gutPyI= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -175,6 +208,7 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 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.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= @@ -189,6 +223,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -205,11 +240,14 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -232,22 +270,29 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 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= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc h1:ZQrgZFsLzkw7o3CoDzsfBhx0bf/1rVBXrLy8dXKRe8o= github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc/go.mod h1:PyXUpnI3olx3bsPcHt98FGPX/KCFZ1Fi+hw1XLI6384= 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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= 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.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= 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.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -260,9 +305,31 @@ 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.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.4.0/go.mod h1:PvmtTvhVqKDzDQy4d3bWzPjZLzom4iQbAZy2sgZ/qI8= +github.com/labstack/echo/v4 v4.6.1/go.mod h1:RnjgMWNDB9g/HucVWhQYNQP9PvbYf6adqftqryo7s9k= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lestrrat-go/backoff/v2 v2.0.7/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +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/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4= +github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= +github.com/lestrrat-go/codegen v1.0.0/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM= +github.com/lestrrat-go/codegen v1.0.2/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM= +github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc= +github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE= +github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A= +github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= +github.com/lestrrat-go/jwx v1.2.4/go.mod h1:CAe9Z479rJwIYDR2DqWwMm9c+gCNoYB6+0wBxPkEh0Q= +github.com/lestrrat-go/jwx v1.2.7 h1:wO7fEc3PW56wpQBMU5CyRkrk4DVsXxCoJg7oIm5HHE4= +github.com/lestrrat-go/jwx v1.2.7/go.mod h1:bw24IXWbavc0R2RsOtpXL7RtMyP589yZ1+L7kd09ZGA= +github.com/lestrrat-go/option v0.0.0-20210103042652-6f1ecfceda35/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/pdebug/v3 v3.0.1/go.mod h1:za+m+Ve24yCxTEhR59N7UlnJomWwCiIqbJRmKeiADU4= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -273,10 +340,14 @@ github.com/manicminer/hamilton v0.31.1/go.mod h1:QryxpD/4+cdKuXNi0UjLDvgxYdP0LLm github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo= github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.10/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= @@ -296,6 +367,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 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= @@ -309,6 +381,7 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -320,6 +393,7 @@ github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= @@ -364,12 +438,16 @@ 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 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 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.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -384,18 +462,60 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/btree v0.0.0-20191029221954-400434d76274 h1:G6Z6HvJuPjG6XfNGi/feOATzeJrfgTNJY+rGrHbA04E= +github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8= +github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo= +github.com/tidwall/buntdb v1.1.2/go.mod h1:xAzi36Hir4FarpSHyfuZ6JzPJdjRZ8QlLZSntE2mqlI= +github.com/tidwall/gjson v1.3.4/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= +github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb h1:5NSYaAdrnblKByzd7XByQEJVT8+9v0W/tIY0Oo4OwrE= +github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb/go.mod h1:lKYYLFIr9OIgdgrtgkZ9zgRxRdvPYsExnYBsEAd8W5M= +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= +github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e h1:+NL1GDIUOKxVfbp2KoJQD9cTQ6dyP2co9q4yzmT9FZo= +github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e/go.mod h1:/h+UnNGt0IhNNJLkGikcdcJqm66zGD/uJGMRxK/9+Ao= +github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 h1:Otn9S136ELckZ3KKDyCkxapfufrqDqwmGjcHfAyXRrE= +github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563/go.mod h1:mLqSmt7Dv/CNneF2wfcChfN1rvapyQr01LGKnKex0DQ= 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/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.14.0/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE= +github.com/valyala/fasthttp v1.29.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +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 v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xenitab/dispans v0.0.3 h1:nYbO0vxokhydV7pl2XIqla7iNSt9iJHTWCbG0GOmx8A= +github.com/xenitab/dispans v0.0.3/go.mod h1:Nz+rsexK3w3Af7SmkVB0oKt6jJ6eFHL01F8w6LcCyEI= +github.com/xenitab/go-oidc-middleware v0.0.14 h1:Gqg2haUnj2GQF8qHltkJhuI6pwytnbfqwzLTF/XsAT4= +github.com/xenitab/go-oidc-middleware v0.0.14/go.mod h1:7F+WBiwhMNTe7o6cKid67XRiqkFWucnoxI7JJDbPokU= +github.com/xenitab/pkg v0.0.2/go.mod h1:Y8WrydjgisWoExwdlN8hs6SK9seZ3lgV5Tpub3pOw6o= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/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.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw= github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= +github.com/zclconf/go-cty v1.9.1 h1:viqrgQwFl5UpSxc046qblj78wZXVDFnSOufaOTER+cc= +github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -410,6 +530,8 @@ go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpK go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= +go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= @@ -421,9 +543,12 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -456,7 +581,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= 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= @@ -493,9 +620,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 h1:Z04ewVs7JhXaYkmDhBERPi41gnltfQpMWDnTnQbaCqk= golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -504,6 +634,7 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -525,6 +656,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -562,10 +694,13 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/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-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= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -573,6 +708,9 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211003122950-b1ebd4e1001c h1:EyJTLQbOxvk8V6oDdD8ILR1BOs3nEJXThD6aqsiPNkM= golang.org/x/sys v0.0.0-20211003122950-b1ebd4e1001c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -586,12 +724,14 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -600,6 +740,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 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-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= @@ -637,9 +778,13 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -762,6 +907,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk= diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index 5ab11b9d..8e66c1c4 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -15,6 +15,7 @@ import ( "github.com/xenitab/azad-kube-proxy/pkg/models" "github.com/xenitab/azad-kube-proxy/pkg/user" "github.com/xenitab/azad-kube-proxy/pkg/util" + "github.com/xenitab/go-oidc-middleware/options" ) const ( @@ -100,31 +101,87 @@ func (client *Client) LivenessHandler(ctx context.Context) func(http.ResponseWri } } +type azureClaims struct { + sub string + username string + objectID string + groups []string +} + +func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { + rawSub, ok := rawClaims["sub"] + if !ok { + return azureClaims{}, fmt.Errorf("unable to find sub claim") + } + + sub, ok := rawSub.(string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast sub to string", "sub", rawSub) + } + + isServicePrincipal := false + rawUsername, ok := rawClaims["preferred_username"] + if !ok { + isServicePrincipal = true + } + + username := "" + if !isServicePrincipal { + username, ok = rawUsername.(string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast preferred_username to string", "preferred_username", rawUsername) + } + } + + rawObjectID, ok := rawClaims["oid"] + if !ok { + return azureClaims{}, fmt.Errorf("unable to find oid claim") + } + + objectID, ok := rawObjectID.(string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast oid to string", "oid", rawObjectID) + } + + rawGroups, ok := rawClaims["groups"] + if !ok { + return azureClaims{}, fmt.Errorf("unable to find groups claim") + } + + groups, ok := rawGroups.([]string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast groups to []string", "groups", rawGroups) + } + + return azureClaims{ + sub: sub, + username: username, + objectID: objectID, + groups: groups, + }, nil +} + // AzadKubeProxyHandler ... func (client *Client) AzadKubeProxyHandler(ctx context.Context, p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) { log := logr.FromContextOrDiscard(ctx) return func(w http.ResponseWriter, r *http.Request) { - // Extract token from Authorization header - token, err := util.GetBearerToken(r) - if err != nil { - log.Error(err, "Unable to extract Bearer token") - http.Error(w, "Unable to extract Bearer token", http.StatusForbidden) + rawClaims, ok := r.Context().Value(options.DefaultClaimsContextKeyName).(map[string]interface{}) + if !ok { + log.Error(fmt.Errorf("unable to typecast claims"), "not able to typecast claims to map[string]interface{}") + http.Error(w, "Unexpected error", http.StatusInternalServerError) return } - tokenHash := util.GetEncodedHash(token) - - // Verify user token - verifiedToken, err := client.OIDCVerifier.Verify(ctx, token) + claims, err := toAzureClaims(rawClaims) if err != nil { - log.Error(err, "Unable to verify token") - http.Error(w, "Unable to verify token", http.StatusUnauthorized) + log.Error(err, "not able to convert rawClaims to azureClaims") + http.Error(w, "Unexpected error", http.StatusInternalServerError) return } // Use the token hash to get the user object from cache - user, found, err := client.CacheClient.GetUser(ctx, tokenHash) + user, found, err := client.CacheClient.GetUser(ctx, claims.sub) if err != nil { log.Error(err, "Unable to get cached user object") http.Error(w, "Unexpected error", http.StatusInternalServerError) @@ -142,15 +199,8 @@ func (client *Client) AzadKubeProxyHandler(ctx context.Context, p *httputil.Reve // Get the user from the token if no cache was found if !found { - claims, err := client.ClaimsClient.NewClaims(verifiedToken) - if err != nil { - log.Error(err, "Unable to get claims") - http.Error(w, "Unable to get claims", http.StatusForbidden) - return - } - // Get the user object - user, err = client.UserClient.GetUser(ctx, claims.Username, claims.ObjectID) + user, err = client.UserClient.GetUser(ctx, claims.username, claims.objectID) if err != nil { log.Error(err, "Unable to get user") http.Error(w, "Unable to get user", http.StatusForbidden) @@ -164,7 +214,7 @@ func (client *Client) AzadKubeProxyHandler(ctx context.Context, p *httputil.Reve return } - err = client.CacheClient.SetUser(ctx, tokenHash, user) + err = client.CacheClient.SetUser(ctx, claims.sub, user) if err != nil { log.Error(err, "Unable to set cache for user object") http.Error(w, "Unexpected error", http.StatusInternalServerError) diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index 29241173..351a7fe7 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -23,6 +23,8 @@ import ( "github.com/xenitab/azad-kube-proxy/pkg/health" "github.com/xenitab/azad-kube-proxy/pkg/metrics" "github.com/xenitab/azad-kube-proxy/pkg/user" + "github.com/xenitab/go-oidc-middleware/oidchttp" + "github.com/xenitab/go-oidc-middleware/options" "golang.org/x/sync/errgroup" ) @@ -157,7 +159,18 @@ func (client *Client) Start(ctx context.Context) error { return err } - router.PathPrefix("/").HandlerFunc(proxyHandlers.AzadKubeProxyHandler(ctx, proxy)) + oidcHandler := oidchttp.New(http.HandlerFunc(proxyHandlers.AzadKubeProxyHandler(ctx, proxy)), + options.WithIssuer(fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", client.Config.TenantID)), + options.WithRequiredTokenType("JWT"), + options.WithRequiredAudience(client.Config.TenantID), + options.WithFallbackSignatureAlgorithm("RS256"), + options.WithRequiredClaims(map[string]interface{}{ + "tid": client.Config.TenantID, + }), + ) + + router.PathPrefix("/").Handler(oidcHandler) + router.Use(client.CORSClient.Middleware) httpServer := client.getHTTPServer(router) From 929f49b1441a7255f577591faca0696169f48901 Mon Sep 17 00:00:00 2001 From: Simon Gottschlag Date: Thu, 7 Oct 2021 11:29:43 +0200 Subject: [PATCH 3/5] fix error formatting --- pkg/handlers/handlers.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index 8e66c1c4..86e35ab3 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -116,7 +116,7 @@ func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { sub, ok := rawSub.(string) if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast sub to string", "sub", rawSub) + return azureClaims{}, fmt.Errorf("unable to typecast sub to string: %v", rawSub) } isServicePrincipal := false @@ -129,7 +129,7 @@ func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { if !isServicePrincipal { username, ok = rawUsername.(string) if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast preferred_username to string", "preferred_username", rawUsername) + return azureClaims{}, fmt.Errorf("unable to typecast preferred_username to string: %v", rawUsername) } } @@ -140,7 +140,7 @@ func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { objectID, ok := rawObjectID.(string) if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast oid to string", "oid", rawObjectID) + return azureClaims{}, fmt.Errorf("unable to typecast oid to string: %v", rawObjectID) } rawGroups, ok := rawClaims["groups"] @@ -150,7 +150,7 @@ func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { groups, ok := rawGroups.([]string) if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast groups to []string", "groups", rawGroups) + return azureClaims{}, fmt.Errorf("unable to typecast groups to []string: %v", rawGroups) } return azureClaims{ From 102339aa8abe283894294b33ad4a2110675b5188 Mon Sep 17 00:00:00 2001 From: Simon Gottschlag Date: Thu, 7 Oct 2021 15:25:32 +0200 Subject: [PATCH 4/5] update tests to work with middleware --- pkg/handlers/azure.go | 62 ++++++++++++++++++++ pkg/handlers/handlers.go | 64 +------------------- pkg/handlers/handlers_test.go | 106 +++++++++++++++++----------------- pkg/handlers/oidc.go | 25 ++++++++ pkg/proxy/proxy.go | 12 +--- 5 files changed, 142 insertions(+), 127 deletions(-) create mode 100644 pkg/handlers/azure.go create mode 100644 pkg/handlers/oidc.go diff --git a/pkg/handlers/azure.go b/pkg/handlers/azure.go new file mode 100644 index 00000000..bf84d8a7 --- /dev/null +++ b/pkg/handlers/azure.go @@ -0,0 +1,62 @@ +package handlers + +import "fmt" + +// azureClaims contains the claims used by the Azure AD Access Token (v2) +type azureClaims struct { + sub string + username string + objectID string + groups []string +} + +// toAzureClaims converts the raw claims from context.Value() to azureClaims +func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { + rawSub, ok := rawClaims["sub"] + if !ok { + return azureClaims{}, fmt.Errorf("unable to find sub claim") + } + + sub, ok := rawSub.(string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast sub to string: %v", rawSub) + } + + isServicePrincipal := false + rawUsername, ok := rawClaims["preferred_username"] + if !ok { + isServicePrincipal = true + } + + username := "" + if !isServicePrincipal { + username, ok = rawUsername.(string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast preferred_username to string: %v", rawUsername) + } + } + + rawObjectID, ok := rawClaims["oid"] + if !ok { + return azureClaims{}, fmt.Errorf("unable to find oid claim") + } + + objectID, ok := rawObjectID.(string) + if !ok { + return azureClaims{}, fmt.Errorf("unable to typecast oid to string: %v", rawObjectID) + } + + rawGroups := rawClaims["groups"] + groups, ok := rawGroups.([]string) + if !ok { + // if we are unable to typecast, set groups to empty + groups = []string{} + } + + return azureClaims{ + sub: sub, + username: username, + objectID: objectID, + groups: groups, + }, nil +} diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index 86e35ab3..c84fb73b 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -101,66 +101,6 @@ func (client *Client) LivenessHandler(ctx context.Context) func(http.ResponseWri } } -type azureClaims struct { - sub string - username string - objectID string - groups []string -} - -func toAzureClaims(rawClaims map[string]interface{}) (azureClaims, error) { - rawSub, ok := rawClaims["sub"] - if !ok { - return azureClaims{}, fmt.Errorf("unable to find sub claim") - } - - sub, ok := rawSub.(string) - if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast sub to string: %v", rawSub) - } - - isServicePrincipal := false - rawUsername, ok := rawClaims["preferred_username"] - if !ok { - isServicePrincipal = true - } - - username := "" - if !isServicePrincipal { - username, ok = rawUsername.(string) - if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast preferred_username to string: %v", rawUsername) - } - } - - rawObjectID, ok := rawClaims["oid"] - if !ok { - return azureClaims{}, fmt.Errorf("unable to find oid claim") - } - - objectID, ok := rawObjectID.(string) - if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast oid to string: %v", rawObjectID) - } - - rawGroups, ok := rawClaims["groups"] - if !ok { - return azureClaims{}, fmt.Errorf("unable to find groups claim") - } - - groups, ok := rawGroups.([]string) - if !ok { - return azureClaims{}, fmt.Errorf("unable to typecast groups to []string: %v", rawGroups) - } - - return azureClaims{ - sub: sub, - username: username, - objectID: objectID, - groups: groups, - }, nil -} - // AzadKubeProxyHandler ... func (client *Client) AzadKubeProxyHandler(ctx context.Context, p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) { log := logr.FromContextOrDiscard(ctx) @@ -209,7 +149,7 @@ func (client *Client) AzadKubeProxyHandler(ctx context.Context, p *httputil.Reve // Check if number of groups more than the configured limit if len(user.Groups) > client.Config.AzureADMaxGroupCount-1 { - log.Error(errors.New("Max groups reached"), "The user is member of more groups than allowed to be passed to the Kubernetes API", "groupCount", len(user.Groups), "username", user.Username, "config.AzureADMaxGroupCount", client.Config.AzureADMaxGroupCount) + log.Error(errors.New("max groups reached"), "the user is member of more groups than allowed to be passed to the Kubernetes API", "groupCount", len(user.Groups), "username", user.Username, "config.AzureADMaxGroupCount", client.Config.AzureADMaxGroupCount) http.Error(w, "Too many groups", http.StatusForbidden) return } @@ -243,7 +183,7 @@ func (client *Client) AzadKubeProxyHandler(ctx context.Context, p *httputil.Reve case models.ObjectIDGroupIdentifier: r.Header.Add(impersonateGroupHeader, group.ObjectID) default: - log.Error(errors.New("Unknown groups identifier"), "Unknown groups identifier", "GroupIdentifier", client.Config.GroupIdentifier) + log.Error(errors.New("unknown groups identifier"), "unknown groups identifier", "GroupIdentifier", client.Config.GroupIdentifier) http.Error(w, "Unexpected error", http.StatusInternalServerError) return } diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go index 0a0d99b5..bcc9337f 100644 --- a/pkg/handlers/handlers_test.go +++ b/pkg/handlers/handlers_test.go @@ -53,11 +53,6 @@ func TestNewHandlersClient(t *testing.T) { if err != nil { t.Errorf("Expected err to be nil but it was %q", err) } - - _, err = NewHandlersClient(ctx, cfg, fakeCacheClient, fakeUserClient, fakeHealthClient) - if !strings.Contains(err.Error(), "fake error") { - t.Errorf("Expected err to contain 'fake error' but it was %q", err) - } } func TestReadinessHandler(t *testing.T) { @@ -236,6 +231,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { } cases := []struct { + testDescription string request *http.Request config config.Config configFunction func(oldConfig config.Config) config.Config @@ -244,9 +240,11 @@ func TestAzadKubeProxyHandler(t *testing.T) { userClient user.ClientInterface userFunction func(oldUserClient user.ClientInterface) user.ClientInterface expectedResCode int + expectedResBody string expectedErrContains string }{ { + testDescription: "working token, fake user client", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -256,13 +254,14 @@ func TestAzadKubeProxyHandler(t *testing.T) { "Authorization": {fmt.Sprintf("Bearer %s", token.Token)}, }, }, - config: cfg, - cacheClient: memCacheClient, - userClient: fakeUserClient, - expectedResCode: http.StatusOK, - expectedErrContains: "", + config: cfg, + cacheClient: memCacheClient, + userClient: fakeUserClient, + expectedResCode: http.StatusOK, + expectedResBody: `{"fake": true}`, }, { + testDescription: "no token", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -272,12 +271,13 @@ func TestAzadKubeProxyHandler(t *testing.T) { "Authorization": {"Bearer"}, }, }, - config: cfg, - cacheClient: memCacheClient, - expectedResCode: http.StatusForbidden, - expectedErrContains: "Unable to extract Bearer token", + config: cfg, + cacheClient: memCacheClient, + expectedResCode: http.StatusBadRequest, + expectedResBody: "", }, { + testDescription: "fake token", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -287,13 +287,14 @@ func TestAzadKubeProxyHandler(t *testing.T) { "Authorization": {"Bearer fake-token"}, }, }, - config: cfg, - cacheClient: memCacheClient, - userClient: fakeUserClient, - expectedResCode: http.StatusUnauthorized, - expectedErrContains: "Unable to verify token", + config: cfg, + cacheClient: memCacheClient, + userClient: fakeUserClient, + expectedResCode: http.StatusUnauthorized, + expectedResBody: "", }, { + testDescription: "working token, fake user client and cache", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -303,13 +304,14 @@ func TestAzadKubeProxyHandler(t *testing.T) { "Authorization": {fmt.Sprintf("Bearer %s", token.Token)}, }, }, - config: cfg, - cacheClient: fakeCacheClient, - userClient: fakeUserClient, - expectedResCode: http.StatusOK, - expectedErrContains: "", + config: cfg, + cacheClient: fakeCacheClient, + userClient: fakeUserClient, + expectedResCode: http.StatusOK, + expectedResBody: `{"fake": true}`, }, { + testDescription: "fake token", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -319,13 +321,14 @@ func TestAzadKubeProxyHandler(t *testing.T) { "Authorization": {"Bearer fake-token"}, }, }, - config: cfg, - cacheClient: fakeCacheClient, - userClient: fakeUserClient, - expectedResCode: http.StatusUnauthorized, - expectedErrContains: "Unable to verify token", + config: cfg, + cacheClient: fakeCacheClient, + userClient: fakeUserClient, + expectedResCode: http.StatusUnauthorized, + expectedResBody: "", }, { + testDescription: "working token, error from cache", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -342,6 +345,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "Unexpected error", }, { + testDescription: "working token, with imperonate-user header first", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -359,6 +363,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "User unauthorized", }, { + testDescription: "working token, with imperonate-user header last", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -376,6 +381,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "User unauthorized", }, { + testDescription: "working token, with imperonate-user header and fake-header", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -394,6 +400,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "User unauthorized", }, { + testDescription: "working token, with imperonate-group header and fake-header", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -412,22 +419,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "User unauthorized", }, { - request: &http.Request{ - Method: "GET", - URL: &url.URL{ - Path: "/", - }, - Header: map[string][]string{ - "Authorization": {fmt.Sprintf("Bearer %s", token.Token)}, - }, - }, - config: cfg, - cacheClient: fakeCacheClient, - userClient: fakeUserClient, - expectedResCode: http.StatusForbidden, - expectedErrContains: "Unable to get claims", - }, - { + testDescription: "working token, userClient error", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -444,6 +436,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "Unable to get user", }, { + testDescription: "working token, with multiple fake groups", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -472,6 +465,7 @@ func TestAzadKubeProxyHandler(t *testing.T) { expectedErrContains: "Too many groups", }, { + testDescription: "working token, using ObjectIDGroupIdentifier", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -486,12 +480,13 @@ func TestAzadKubeProxyHandler(t *testing.T) { oldConfig.GroupIdentifier = models.ObjectIDGroupIdentifier return oldConfig }, - cacheClient: memCacheClient, - userClient: fakeUserClient, - expectedResCode: http.StatusOK, - expectedErrContains: "", + cacheClient: memCacheClient, + userClient: fakeUserClient, + expectedResCode: http.StatusOK, + expectedResBody: `{"fake": true}`, }, { + testDescription: "working token, with wrong GroupIdentifier", request: &http.Request{ Method: "GET", URL: &url.URL{ @@ -513,7 +508,8 @@ func TestAzadKubeProxyHandler(t *testing.T) { }, } - for _, c := range cases { + for i, c := range cases { + t.Logf("Test #%d: %s", i, c.testDescription) if c.configFunction != nil { c.config = c.configFunction(c.config) } @@ -535,16 +531,18 @@ func TestAzadKubeProxyHandler(t *testing.T) { proxy.ErrorHandler = proxyHandlers.ErrorHandler(ctx) rr := httptest.NewRecorder() router := mux.NewRouter() - router.PathPrefix("/").HandlerFunc(proxyHandlers.AzadKubeProxyHandler(ctx, proxy)) + + oidcHandler := NewOIDCHandler(proxyHandlers.AzadKubeProxyHandler(ctx, proxy), tenantID, clientID) + router.PathPrefix("/").Handler(oidcHandler) + router.ServeHTTP(rr, c.request) if rr.Code != c.expectedResCode { t.Errorf("Handler returned unexpected status code.\nExpected: %d\nActual: %d", c.expectedResCode, rr.Code) } - expected := `{"fake": true}` - if rr.Body.String() != expected && c.expectedErrContains == "" { - t.Errorf("Handler returned unexpected body.\nExpected: %s\nActual: %s", expected, rr.Body.String()) + if rr.Body.String() != c.expectedResBody && c.expectedErrContains == "" { + t.Errorf("Handler returned unexpected body.\nExpected: %s\nActual: %s", c.expectedResBody, rr.Body.String()) } if c.expectedErrContains != "" { diff --git a/pkg/handlers/oidc.go b/pkg/handlers/oidc.go new file mode 100644 index 00000000..965176e6 --- /dev/null +++ b/pkg/handlers/oidc.go @@ -0,0 +1,25 @@ +package handlers + +import ( + "fmt" + "net/http" + + "github.com/xenitab/go-oidc-middleware/oidchttp" + "github.com/xenitab/go-oidc-middleware/options" +) + +// NewOIDCHandler returns a http.Handler to take care of the JWT validation +func NewOIDCHandler(h http.HandlerFunc, tenantID string, clientID string) http.Handler { + oidcHandler := oidchttp.New(h, + options.WithIssuer(fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", tenantID)), + options.WithRequiredTokenType("JWT"), + options.WithRequiredAudience(clientID), + options.WithFallbackSignatureAlgorithm("RS256"), + options.WithRequiredClaims(map[string]interface{}{ + "tid": tenantID, + }), + options.WithLazyLoadJwks(true), + ) + + return oidcHandler +} diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index 351a7fe7..0bf0793a 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -23,8 +23,6 @@ import ( "github.com/xenitab/azad-kube-proxy/pkg/health" "github.com/xenitab/azad-kube-proxy/pkg/metrics" "github.com/xenitab/azad-kube-proxy/pkg/user" - "github.com/xenitab/go-oidc-middleware/oidchttp" - "github.com/xenitab/go-oidc-middleware/options" "golang.org/x/sync/errgroup" ) @@ -159,15 +157,7 @@ func (client *Client) Start(ctx context.Context) error { return err } - oidcHandler := oidchttp.New(http.HandlerFunc(proxyHandlers.AzadKubeProxyHandler(ctx, proxy)), - options.WithIssuer(fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", client.Config.TenantID)), - options.WithRequiredTokenType("JWT"), - options.WithRequiredAudience(client.Config.TenantID), - options.WithFallbackSignatureAlgorithm("RS256"), - options.WithRequiredClaims(map[string]interface{}{ - "tid": client.Config.TenantID, - }), - ) + oidcHandler := handlers.NewOIDCHandler(proxyHandlers.AzadKubeProxyHandler(ctx, proxy), client.Config.TenantID, client.Config.ClientID) router.PathPrefix("/").Handler(oidcHandler) From 26768cb90d1cda4a43a256f9d3d9bd6cbf483136 Mon Sep 17 00:00:00 2001 From: Simon Gottschlag Date: Thu, 7 Oct 2021 15:25:36 +0200 Subject: [PATCH 5/5] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1ec62d30..706c15eb 100644 --- a/README.md +++ b/README.md @@ -292,8 +292,8 @@ metadata: type: kubernetes.io/service-account-token EOF -kubectl get secret azad-kube-proxy-test-secret --output=jsonpath={.data.ca\\.crt} | base64 -d > tmp/ca.crt -kubectl get secret azad-kube-proxy-test-secret --output=jsonpath={.data.token} | base64 -d > tmp/token +kubectl --namespace azad-kube-proxy-test get secret azad-kube-proxy-test-secret --output=jsonpath={.data.ca\\.crt} | base64 -d > tmp/ca.crt +kubectl --namespace azad-kube-proxy-test get secret azad-kube-proxy-test-secret --output=jsonpath={.data.token} | base64 -d > tmp/token KUBE_CA_PATH="${PWD}/tmp/ca.crt" KUBE_TOKEN_PATH="${PWD}/tmp/token"