Skip to content
Snippets Groups Projects
Unverified Commit 677ab360 authored by Abhisek Datta's avatar Abhisek Datta Committed by GitHub
Browse files

feat: Add support for configurable prompt type for Google connector (#3475)

parent 1ca45839
No related branches found
No related tags found
No related merge requests found
...@@ -58,6 +58,10 @@ type Config struct { ...@@ -58,6 +58,10 @@ type Config struct {
// If this field is true, fetch direct group membership and transitive group membership // If this field is true, fetch direct group membership and transitive group membership
FetchTransitiveGroupMembership bool `json:"fetchTransitiveGroupMembership"` FetchTransitiveGroupMembership bool `json:"fetchTransitiveGroupMembership"`
// Optional value for the prompt parameter, defaults to consent when offline_access
// scope is requested
PromptType *string `json:"promptType"`
} }
// Open returns a connector which can be used to login users through Google. // Open returns a connector which can be used to login users through Google.
...@@ -107,6 +111,11 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e ...@@ -107,6 +111,11 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
} }
} }
promptType := "consent"
if c.PromptType != nil {
promptType = *c.PromptType
}
clientID := c.ClientID clientID := c.ClientID
return &googleConnector{ return &googleConnector{
redirectURI: c.RedirectURI, redirectURI: c.RedirectURI,
...@@ -128,6 +137,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e ...@@ -128,6 +137,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
domainToAdminEmail: c.DomainToAdminEmail, domainToAdminEmail: c.DomainToAdminEmail,
fetchTransitiveGroupMembership: c.FetchTransitiveGroupMembership, fetchTransitiveGroupMembership: c.FetchTransitiveGroupMembership,
adminSrv: adminSrv, adminSrv: adminSrv,
promptType: promptType,
}, nil }, nil
} }
...@@ -148,6 +158,7 @@ type googleConnector struct { ...@@ -148,6 +158,7 @@ type googleConnector struct {
domainToAdminEmail map[string]string domainToAdminEmail map[string]string
fetchTransitiveGroupMembership bool fetchTransitiveGroupMembership bool
adminSrv map[string]*admin.Service adminSrv map[string]*admin.Service
promptType string
} }
func (c *googleConnector) Close() error { func (c *googleConnector) Close() error {
...@@ -170,8 +181,9 @@ func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string ...@@ -170,8 +181,9 @@ func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string
} }
if s.OfflineAccess { if s.OfflineAccess {
opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "consent")) opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", c.promptType))
} }
return c.oauth2Config.AuthCodeURL(state, opts...), nil return c.oauth2Config.AuthCodeURL(state, opts...), nil
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url"
"os" "os"
"testing" "testing"
...@@ -13,6 +14,8 @@ import ( ...@@ -13,6 +14,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
admin "google.golang.org/api/admin/directory/v1" admin "google.golang.org/api/admin/directory/v1"
"google.golang.org/api/option" "google.golang.org/api/option"
"github.com/dexidp/dex/connector"
) )
var ( var (
...@@ -291,3 +294,60 @@ func TestDomainToAdminEmailConfig(t *testing.T) { ...@@ -291,3 +294,60 @@ func TestDomainToAdminEmailConfig(t *testing.T) {
}) })
} }
} }
func TestPromptTypeConfig(t *testing.T) {
promptTypeLogin := "login"
cases := []struct {
name string
promptType *string
expectedPromptTypeValue string
}{
{
name: "prompt type is nil",
promptType: nil,
expectedPromptTypeValue: "consent",
},
{
name: "prompt type is empty",
promptType: new(string),
expectedPromptTypeValue: "",
},
{
name: "prompt type is set",
promptType: &promptTypeLogin,
expectedPromptTypeValue: "login",
},
}
ts := testSetup()
defer ts.Close()
serviceAccountFilePath, err := tempServiceAccountKey()
assert.Nil(t, err)
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath)
for _, test := range cases {
t.Run(test.name, func(t *testing.T) {
conn, err := newConnector(&Config{
ClientID: "testClient",
ClientSecret: "testSecret",
RedirectURI: ts.URL + "/callback",
Scopes: []string{"openid", "groups", "offline_access"},
DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"},
PromptType: test.promptType,
})
assert.Nil(t, err)
assert.Equal(t, test.expectedPromptTypeValue, conn.promptType)
loginURL, err := conn.LoginURL(connector.Scopes{OfflineAccess: true}, ts.URL+"/callback", "state")
assert.Nil(t, err)
urlp, err := url.Parse(loginURL)
assert.Nil(t, err)
assert.Equal(t, test.expectedPromptTypeValue, urlp.Query().Get("prompt"))
})
}
}
...@@ -75,7 +75,7 @@ type Config struct { ...@@ -75,7 +75,7 @@ type Config struct {
UserNameKey string `json:"userNameKey"` UserNameKey string `json:"userNameKey"`
// PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent) // PromptType will be used for the prompt parameter (when offline_access, by default prompt=consent)
PromptType *string `json:"promptType"` PromptType *string `json:"promptType"`
// OverrideClaimMapping will be used to override the options defined in claimMappings. // OverrideClaimMapping will be used to override the options defined in claimMappings.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment