From 27d7eb532b5809ac8846ad8ab8f76bddeca98593 Mon Sep 17 00:00:00 2001 From: Viacheslav Sychov Date: Sun, 23 Apr 2023 20:41:43 +0200 Subject: [PATCH 1/6] #2895: Add Support for Multiple Admin Emails to Retrieve Group Lists from Different Google Workspaces Signed-off-by: Viacheslav Sychov --- connector/google/google.go | 93 +++++++++++++++++++++++++-------- connector/google/google_test.go | 28 +++++----- 2 files changed, 85 insertions(+), 36 deletions(-) diff --git a/connector/google/google.go b/connector/google/google.go index f80c3586ab..43256216ec 100644 --- a/connector/google/google.go +++ b/connector/google/google.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "os" + "strings" "time" "github.com/coreos/go-oidc/v3/oidc" @@ -22,7 +23,8 @@ import ( ) const ( - issuerURL = "https://accounts.google.com" + issuerURL = "https://accounts.google.com" + wildcardDomainToAdminEmail = "*" ) // Config holds configuration options for Google logins. @@ -46,10 +48,13 @@ type Config struct { // check groups with the admin directory api ServiceAccountFilePath string `json:"serviceAccountFilePath"` + // Deprecated: Use DomainToAdminEmail + AdminEmail string + // Required if ServiceAccountFilePath - // The email of a GSuite super user which the service account will impersonate + // The map workspace domain to email of a GSuite super user which the service account will impersonate // when listing groups - AdminEmail string + DomainToAdminEmail map[string]string // If this field is true, fetch direct group membership and transitive group membership FetchTransitiveGroupMembership bool `json:"fetchTransitiveGroupMembership"` @@ -57,6 +62,14 @@ type Config struct { // Open returns a connector which can be used to login users through Google. func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, err error) { + if len(c.AdminEmail) != 0 { + log.Deprecated(logger, `google: use "domainToAdminEmail.*: %s" option instead of "adminEmail: %s".`, c.AdminEmail, c.AdminEmail) + if c.DomainToAdminEmail == nil { + c.DomainToAdminEmail = make(map[string]string) + } + + c.DomainToAdminEmail[wildcardDomainToAdminEmail] = c.AdminEmail + } ctx, cancel := context.WithCancel(context.Background()) provider, err := oidc.NewProvider(ctx, issuerURL) @@ -72,17 +85,26 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e scopes = append(scopes, "profile", "email") } - var adminSrv *admin.Service + adminSrv := make(map[string]*admin.Service) + + // We know impersonation is required when using a service account credential + // TODO: or is it? + if len(c.DomainToAdminEmail) == 0 && c.ServiceAccountFilePath != "" { + cancel() + return nil, fmt.Errorf("directory service requires adminEmail") + } // Fixing a regression caused by default config fallback: https://github.com/dexidp/dex/issues/2699 - if (c.ServiceAccountFilePath != "" && c.AdminEmail != "") || slices.Contains(scopes, "groups") { - srv, err := createDirectoryService(c.ServiceAccountFilePath, c.AdminEmail, logger) - if err != nil { - cancel() - return nil, fmt.Errorf("could not create directory service: %v", err) - } + if (c.ServiceAccountFilePath != "" && len(c.DomainToAdminEmail) != 0) || slices.Contains(scopes, "groups") { + for domain, adminEmail := range c.DomainToAdminEmail { + srv, err := createDirectoryService(c.ServiceAccountFilePath, adminEmail, logger) + if err != nil { + cancel() + return nil, fmt.Errorf("could not create directory service: %v", err) + } - adminSrv = srv + adminSrv[domain] = srv + } } clientID := c.ClientID @@ -103,7 +125,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e hostedDomains: c.HostedDomains, groups: c.Groups, serviceAccountFilePath: c.ServiceAccountFilePath, - adminEmail: c.AdminEmail, + domainToAdminEmail: c.DomainToAdminEmail, fetchTransitiveGroupMembership: c.FetchTransitiveGroupMembership, adminSrv: adminSrv, }, nil @@ -123,9 +145,9 @@ type googleConnector struct { hostedDomains []string groups []string serviceAccountFilePath string - adminEmail string + domainToAdminEmail map[string]string fetchTransitiveGroupMembership bool - adminSrv *admin.Service + adminSrv map[string]*admin.Service } func (c *googleConnector) Close() error { @@ -226,7 +248,7 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector } var groups []string - if s.Groups && c.adminSrv != nil { + if s.Groups && len(c.adminSrv) != 0 { checkedGroups := make(map[string]struct{}) groups, err = c.getGroups(claims.Email, c.fetchTransitiveGroupMembership, checkedGroups) if err != nil { @@ -258,8 +280,14 @@ func (c *googleConnector) getGroups(email string, fetchTransitiveGroupMembership var userGroups []string var err error groupsList := &admin.Groups{} + domain := c.extractDomainFromEmail(email) + adminSrv, err := c.findAdminService(domain) + if err != nil { + return nil, err + } + for { - groupsList, err = c.adminSrv.Groups.List(). + groupsList, err = adminSrv.Groups.List(). UserKey(email).PageToken(groupsList.NextPageToken).Do() if err != nil { return nil, fmt.Errorf("could not list groups: %v", err) @@ -295,16 +323,37 @@ func (c *googleConnector) getGroups(email string, fetchTransitiveGroupMembership return userGroups, nil } +func (c *googleConnector) findAdminService(domain string) (*admin.Service, error) { + adminSrv, ok := c.adminSrv[domain] + if !ok { + adminSrv, ok = c.adminSrv[wildcardDomainToAdminEmail] + c.logger.Debugf("using wildcard (%s) admin email to fetch groups", c.domainToAdminEmail[wildcardDomainToAdminEmail]) + } + + if !ok { + return nil, fmt.Errorf("unable to find super admin email, domainToAdminEmail for domain: %s not set, %s is also empty", domain, wildcardDomainToAdminEmail) + } + + return adminSrv, nil +} + +// extracts the domain name from an email input. If the email is valid, it returns the domain name after the "@" symbol. +// However, in the case of a broken or invalid email, it returns a wildcard symbol. +func (c *googleConnector) extractDomainFromEmail(email string) string { + at := strings.LastIndex(email, "@") + if at >= 0 { + _, domain := email[:at], email[at+1:] + + return domain + } + + return wildcardDomainToAdminEmail +} + // createDirectoryService sets up super user impersonation and creates an admin client for calling // the google admin api. If no serviceAccountFilePath is defined, the application default credential // is used. func createDirectoryService(serviceAccountFilePath, email string, logger log.Logger) (*admin.Service, error) { - // We know impersonation is required when using a service account credential - // TODO: or is it? - if email == "" && serviceAccountFilePath != "" { - return nil, fmt.Errorf("directory service requires adminEmail") - } - var jsonCredentials []byte var err error diff --git a/connector/google/google_test.go b/connector/google/google_test.go index cf5977ab6a..5c21109ef9 100644 --- a/connector/google/google_test.go +++ b/connector/google/google_test.go @@ -110,7 +110,7 @@ func TestOpen(t *testing.T) { ClientSecret: "testSecret", RedirectURI: ts.URL + "/callback", Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + DomainToAdminEmail: map[string]string{"*": "foo@bar.com"}, ServiceAccountFilePath: "not_found.json", }, expectedErr: "error reading credentials", @@ -121,18 +121,18 @@ func TestOpen(t *testing.T) { ClientSecret: "testSecret", RedirectURI: ts.URL + "/callback", Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + DomainToAdminEmail: map[string]string{"bar.com": "foo@bar.com"}, ServiceAccountFilePath: serviceAccountFilePath, }, expectedErr: "", }, "adc": { config: &Config{ - ClientID: "testClient", - ClientSecret: "testSecret", - RedirectURI: ts.URL + "/callback", - Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"*": "foo@bar.com"}, }, adc: serviceAccountFilePath, expectedErr: "", @@ -143,7 +143,7 @@ func TestOpen(t *testing.T) { ClientSecret: "testSecret", RedirectURI: ts.URL + "/callback", Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + DomainToAdminEmail: map[string]string{"*": "foo@bar.com"}, ServiceAccountFilePath: serviceAccountFilePath, }, adc: "/dev/null", @@ -176,15 +176,15 @@ func TestGetGroups(t *testing.T) { os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath) conn, err := newConnector(&Config{ - ClientID: "testClient", - ClientSecret: "testSecret", - RedirectURI: ts.URL + "/callback", - Scopes: []string{"openid", "groups"}, - AdminEmail: "admin@dexidp.com", + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"*": "admin@dexidp.com"}, }) assert.Nil(t, err) - conn.adminSrv, err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) + conn.adminSrv[wildcardDomainToAdminEmail], err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) assert.Nil(t, err) type testCase struct { userKey string From 3f5e6c7f256280baba5719f32bac4fe803decc73 Mon Sep 17 00:00:00 2001 From: Viacheslav Sychov Date: Wed, 24 May 2023 21:10:49 +0200 Subject: [PATCH 2/6] #2911: adjust code after code review, add more test coverage Signed-off-by: Viacheslav Sychov --- connector/google/google.go | 8 ++--- connector/google/google_test.go | 57 ++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/connector/google/google.go b/connector/google/google.go index 43256216ec..d590867285 100644 --- a/connector/google/google.go +++ b/connector/google/google.go @@ -62,7 +62,7 @@ type Config struct { // Open returns a connector which can be used to login users through Google. func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, err error) { - if len(c.AdminEmail) != 0 { + if c.AdminEmail != "" { log.Deprecated(logger, `google: use "domainToAdminEmail.*: %s" option instead of "adminEmail: %s".`, c.AdminEmail, c.AdminEmail) if c.DomainToAdminEmail == nil { c.DomainToAdminEmail = make(map[string]string) @@ -91,11 +91,11 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e // TODO: or is it? if len(c.DomainToAdminEmail) == 0 && c.ServiceAccountFilePath != "" { cancel() - return nil, fmt.Errorf("directory service requires adminEmail") + return nil, fmt.Errorf("directory service requires the domainToAdminEmail option to be configured") } // Fixing a regression caused by default config fallback: https://github.com/dexidp/dex/issues/2699 - if (c.ServiceAccountFilePath != "" && len(c.DomainToAdminEmail) != 0) || slices.Contains(scopes, "groups") { + if (c.ServiceAccountFilePath != "" && len(c.DomainToAdminEmail) > 0) || slices.Contains(scopes, "groups") { for domain, adminEmail := range c.DomainToAdminEmail { srv, err := createDirectoryService(c.ServiceAccountFilePath, adminEmail, logger) if err != nil { @@ -248,7 +248,7 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector } var groups []string - if s.Groups && len(c.adminSrv) != 0 { + if s.Groups && len(c.adminSrv) > 0 { checkedGroups := make(map[string]struct{}) groups, err = c.getGroups(claims.Email, c.fetchTransitiveGroupMembership, checkedGroups) if err != nil { diff --git a/connector/google/google_test.go b/connector/google/google_test.go index 5c21109ef9..70a17aa3df 100644 --- a/connector/google/google_test.go +++ b/connector/google/google_test.go @@ -102,7 +102,7 @@ func TestOpen(t *testing.T) { Scopes: []string{"openid", "groups"}, ServiceAccountFilePath: serviceAccountFilePath, }, - expectedErr: "requires adminEmail", + expectedErr: "requires the domainToAdminEmail", }, "service_account_key_not_found": { config: &Config{ @@ -236,3 +236,58 @@ func TestGetGroups(t *testing.T) { }) } } + +func TestDomainToAdminEmailConfig(t *testing.T) { + ts := testSetup() + defer ts.Close() + + serviceAccountFilePath, err := tempServiceAccountKey() + assert.Nil(t, err) + + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath) + conn, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + }) + assert.Nil(t, err) + + conn.adminSrv["dexidp.com"], err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) + assert.Nil(t, err) + type testCase struct { + userKey string + expectedErr string + } + + for name, testCase := range map[string]testCase{ + "correct_user_request": { + userKey: "user_1@dexidp.com", + expectedErr: "", + }, + "wrong_user_request": { + userKey: "user_1@foo.bar", + expectedErr: "unable to find super admin email", + }, + "wrong_connector_response": { + userKey: "user_1_foo.bar", + expectedErr: "unable to find super admin email", + }, + } { + testCase := testCase + callCounter = map[string]int{} + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + lookup := make(map[string]struct{}) + + _, err := conn.getGroups(testCase.userKey, true, lookup) + if testCase.expectedErr != "" { + assert.ErrorContains(err, testCase.expectedErr) + } else { + assert.Nil(err) + } + t.Logf("[%s] Amount of API calls per userKey: %+v\n", t.Name(), callCounter) + }) + } +} From eba0f71ebd7924ab9a6c5b92b6c931f62e052857 Mon Sep 17 00:00:00 2001 From: Viacheslav Sychov Date: Thu, 8 Jun 2023 13:17:27 +0200 Subject: [PATCH 3/6] implement groups fetch by default service account from metadata Signed-off-by: Viacheslav Sychov --- connector/google/google.go | 77 +++++++++++++++++++++++--- connector/google/google_test.go | 98 +++++++++++++++++++++++++++++++++ go.mod | 2 +- 3 files changed, 167 insertions(+), 10 deletions(-) diff --git a/connector/google/google.go b/connector/google/google.go index d590867285..203bbd24c4 100644 --- a/connector/google/google.go +++ b/connector/google/google.go @@ -10,11 +10,13 @@ import ( "strings" "time" + "cloud.google.com/go/compute/metadata" "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/exp/slices" "golang.org/x/oauth2" "golang.org/x/oauth2/google" admin "google.golang.org/api/admin/directory/v1" + "google.golang.org/api/impersonate" "google.golang.org/api/option" "github.com/dexidp/dex/connector" @@ -94,8 +96,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e return nil, fmt.Errorf("directory service requires the domainToAdminEmail option to be configured") } - // Fixing a regression caused by default config fallback: https://github.com/dexidp/dex/issues/2699 - if (c.ServiceAccountFilePath != "" && len(c.DomainToAdminEmail) > 0) || slices.Contains(scopes, "groups") { + if (len(c.DomainToAdminEmail) > 0) || slices.Contains(scopes, "groups") { for domain, adminEmail := range c.DomainToAdminEmail { srv, err := createDirectoryService(c.ServiceAccountFilePath, adminEmail, logger) if err != nil { @@ -350,25 +351,83 @@ func (c *googleConnector) extractDomainFromEmail(email string) string { return wildcardDomainToAdminEmail } +// getCredentialsFromFilePath reads and returns the service account credentials from the file at the provided path. +// If an error occurs during the read, it is returned. +func getCredentialsFromFilePath(serviceAccountFilePath string) ([]byte, error) { + jsonCredentials, err := os.ReadFile(serviceAccountFilePath) + if err != nil { + return nil, fmt.Errorf("error reading credentials from file: %v", err) + } + return jsonCredentials, nil +} + +// getCredentialsFromDefault retrieves the application's default credentials. +// If the default credential is empty, it attempts to create a new service with metadata credentials. +// If successful, it returns the service and nil error. +// If unsuccessful, it returns the error and a nil service. +func getCredentialsFromDefault(ctx context.Context, email string, logger log.Logger) ([]byte, *admin.Service, error) { + credential, err := google.FindDefaultCredentials(ctx) + if err != nil { + return nil, nil, fmt.Errorf("failed to fetch application default credentials: %w", err) + } + + if credential.JSON == nil { + logger.Info("JSON is empty, using flow for GCE") + service, err := createServiceWithMetadataServer(ctx, email, logger) + if err != nil { + return nil, nil, err + } + return nil, service, nil + } + + return credential.JSON, nil, nil +} + +// createServiceWithMetadataServer creates a new service using metadata server. +// If an error occurs during the process, it is returned along with a nil service. +func createServiceWithMetadataServer(ctx context.Context, adminEmail string, logger log.Logger) (*admin.Service, error) { + serviceAccountEmail, err := metadata.Email("default") + logger.Infof("discovered serviceAccountEmail: %s", serviceAccountEmail) + + if err != nil { + return nil, fmt.Errorf("unable to get service account email from metadata server: %v", err) + } + + config := impersonate.CredentialsConfig{ + TargetPrincipal: serviceAccountEmail, + Scopes: []string{admin.AdminDirectoryGroupReadonlyScope}, + Lifetime: 0, + Subject: adminEmail, + } + + tokenSource, err := impersonate.CredentialsTokenSource(ctx, config) + if err != nil { + return nil, fmt.Errorf("unable to impersonate with %s, error: %v", adminEmail, err) + } + + return admin.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, tokenSource))) +} + // createDirectoryService sets up super user impersonation and creates an admin client for calling // the google admin api. If no serviceAccountFilePath is defined, the application default credential // is used. -func createDirectoryService(serviceAccountFilePath, email string, logger log.Logger) (*admin.Service, error) { +func createDirectoryService(serviceAccountFilePath, email string, logger log.Logger) (service *admin.Service, err error) { var jsonCredentials []byte - var err error ctx := context.Background() if serviceAccountFilePath == "" { logger.Warn("the application default credential is used since the service account file path is not used") - credential, err := google.FindDefaultCredentials(ctx) + jsonCredentials, service, err = getCredentialsFromDefault(ctx, email, logger) if err != nil { - return nil, fmt.Errorf("failed to fetch application default credentials: %w", err) + return + } + if service != nil { + return } - jsonCredentials = credential.JSON } else { - jsonCredentials, err = os.ReadFile(serviceAccountFilePath) + jsonCredentials, err = getCredentialsFromFilePath(serviceAccountFilePath) if err != nil { - return nil, fmt.Errorf("error reading credentials from file: %v", err) + return } } config, err := google.JWTConfigFromJSON(jsonCredentials, admin.AdminDirectoryGroupReadonlyScope) diff --git a/connector/google/google_test.go b/connector/google/google_test.go index aaefb87994..ff981ed147 100644 --- a/connector/google/google_test.go +++ b/connector/google/google_test.go @@ -7,6 +7,7 @@ import ( "net/http" "net/http/httptest" "os" + "strings" "testing" "github.com/sirupsen/logrus" @@ -291,3 +292,100 @@ func TestDomainToAdminEmailConfig(t *testing.T) { }) } } + +var gceMetadataFlags = map[string]bool{ + "failOnEmailRequest": false, +} + +func mockGCEMetadataServer() *httptest.Server { + mux := http.NewServeMux() + + mux.HandleFunc("/computeMetadata/v1/instance/service-accounts/default/email", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + if gceMetadataFlags["failOnEmailRequest"] { + w.WriteHeader(http.StatusBadRequest) + } + json.NewEncoder(w).Encode("my-service-account@example-project.iam.gserviceaccount.com") + }) + mux.HandleFunc("/computeMetadata/v1/instance/service-accounts/default/token", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + json.NewEncoder(w).Encode(struct { + AccessToken string `json:"access_token"` + ExpiresInSec int `json:"expires_in"` + TokenType string `json:"token_type"` + }{ + AccessToken: "my-example.token", + ExpiresInSec: 3600, + TokenType: "Bearer", + }) + }) + + return httptest.NewServer(mux) +} + +func TestGCEWorkloadIdentity(t *testing.T) { + ts := testSetup() + defer ts.Close() + + metadataServer := mockGCEMetadataServer() + defer metadataServer.Close() + metadataServerHost := strings.Replace(metadataServer.URL, "http://", "", 1) + + os.Setenv("GCE_METADATA_HOST", metadataServerHost) + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "") + os.Setenv("HOME", "/tmp") + + gceMetadataFlags["failOnEmailRequest"] = true + _, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + }) + assert.Error(t, err) + + gceMetadataFlags["failOnEmailRequest"] = false + conn, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + }) + assert.Nil(t, err) + + conn.adminSrv["dexidp.com"], err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) + assert.Nil(t, err) + type testCase struct { + userKey string + expectedErr string + } + + for name, testCase := range map[string]testCase{ + "correct_user_request": { + userKey: "user_1@dexidp.com", + expectedErr: "", + }, + "wrong_user_request": { + userKey: "user_1@foo.bar", + expectedErr: "unable to find super admin email", + }, + "wrong_connector_response": { + userKey: "user_1_foo.bar", + expectedErr: "unable to find super admin email", + }, + } { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + lookup := make(map[string]struct{}) + + _, err := conn.getGroups(testCase.userKey, true, lookup) + if testCase.expectedErr != "" { + assert.ErrorContains(err, testCase.expectedErr) + } else { + assert.Nil(err) + } + }) + } +} diff --git a/go.mod b/go.mod index 00e3c1b51b..5919777fdb 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/dexidp/dex go 1.20 require ( + cloud.google.com/go/compute/metadata v0.2.3 entgo.io/ent v0.12.3 github.com/AppsFlyer/go-sundheit v0.5.0 github.com/Masterminds/semver v1.5.0 @@ -43,7 +44,6 @@ require ( require ( ariga.io/atlas v0.10.2-0.20230427182402-87a07dfb83bf // indirect cloud.google.com/go/compute v1.19.3 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect From 3f8824f68bdd386c5dcb84ed3f2f93c78bf84ec8 Mon Sep 17 00:00:00 2001 From: Maksim Nabokikh Date: Tue, 24 Oct 2023 13:19:18 +0200 Subject: [PATCH 4/6] Update go.mod Signed-off-by: Maksim Nabokikh --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index 4b100e776f..f68554c2cd 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,6 @@ require ( require ( ariga.io/atlas v0.14.1-0.20230918065911-83ad451a4935 // indirect cloud.google.com/go/compute v1.23.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect From fe95efd1590d009ebbe73891903f561af271679c Mon Sep 17 00:00:00 2001 From: Maksim Nabokikh Date: Wed, 29 May 2024 11:43:01 +0200 Subject: [PATCH 5/6] Update go.mod Signed-off-by: Maksim Nabokikh --- go.mod | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cb0969864f..80349c2a5a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/dexidp/dex go 1.21 require ( - cloud.google.com/go/compute/metadata v0.2.3 + cloud.google.com/go/compute/metadata v0.3.0 entgo.io/ent v0.13.1 github.com/AppsFlyer/go-sundheit v0.5.0 github.com/Masterminds/semver v1.5.0 @@ -46,8 +46,6 @@ require ( ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect cloud.google.com/go/auth v0.4.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect - cloud.google.com/go/compute v1.23.4 // indirect - cloud.google.com/go/compute/metadata v0.3.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/Masterminds/goutils v1.1.1 // indirect From d9b133d513fcbc229cb0832d4f4e9da372c8eeca Mon Sep 17 00:00:00 2001 From: Maksim Nabokikh Date: Wed, 29 May 2024 11:50:17 +0200 Subject: [PATCH 6/6] Update google_test.go Signed-off-by: Maksim Nabokikh --- connector/google/google_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connector/google/google_test.go b/connector/google/google_test.go index 8668dbe3af..2fa2b783ef 100644 --- a/connector/google/google_test.go +++ b/connector/google/google_test.go @@ -389,10 +389,10 @@ func TestGCEWorkloadIdentity(t *testing.T) { } else { assert.Nil(err) } - }) - } + }) + } } - + func TestPromptTypeConfig(t *testing.T) { promptTypeLogin := "login" cases := []struct {