Skip to content

Commit aef0bca

Browse files
committed
feat: Add support for configurable prompt type for Google connector
Signed-off-by: abhisek <abhisek.datta@gmail.com>
1 parent 1ca4583 commit aef0bca

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

connector/google/google.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ type Config struct {
5858

5959
// If this field is true, fetch direct group membership and transitive group membership
6060
FetchTransitiveGroupMembership bool `json:"fetchTransitiveGroupMembership"`
61+
62+
// Optional value for the prompt parameter, defaults to consent when offline_access
63+
// scope is requested
64+
PromptType *string `json:"promptType"`
6165
}
6266

6367
// 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
107111
}
108112
}
109113

114+
promptType := "consent"
115+
if c.PromptType != nil {
116+
promptType = *c.PromptType
117+
}
118+
110119
clientID := c.ClientID
111120
return &googleConnector{
112121
redirectURI: c.RedirectURI,
@@ -128,6 +137,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
128137
domainToAdminEmail: c.DomainToAdminEmail,
129138
fetchTransitiveGroupMembership: c.FetchTransitiveGroupMembership,
130139
adminSrv: adminSrv,
140+
promptType: promptType,
131141
}, nil
132142
}
133143

@@ -148,6 +158,7 @@ type googleConnector struct {
148158
domainToAdminEmail map[string]string
149159
fetchTransitiveGroupMembership bool
150160
adminSrv map[string]*admin.Service
161+
promptType string
151162
}
152163

153164
func (c *googleConnector) Close() error {
@@ -170,8 +181,9 @@ func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string
170181
}
171182

172183
if s.OfflineAccess {
173-
opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "consent"))
184+
opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", c.promptType))
174185
}
186+
175187
return c.oauth2Config.AuthCodeURL(state, opts...), nil
176188
}
177189

connector/google/google_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import (
66
"fmt"
77
"net/http"
88
"net/http/httptest"
9+
"net/url"
910
"os"
1011
"testing"
1112

13+
"github.com/dexidp/dex/connector"
1214
"github.com/sirupsen/logrus"
1315
"github.com/stretchr/testify/assert"
1416
admin "google.golang.org/api/admin/directory/v1"
@@ -291,3 +293,60 @@ func TestDomainToAdminEmailConfig(t *testing.T) {
291293
})
292294
}
293295
}
296+
297+
func TestPromptTypeConfig(t *testing.T) {
298+
promptTypeLogin := "login"
299+
cases := []struct {
300+
name string
301+
promptType *string
302+
expectedPromptTypeValue string
303+
}{
304+
{
305+
name: "prompt type is nil",
306+
promptType: nil,
307+
expectedPromptTypeValue: "consent",
308+
},
309+
{
310+
name: "prompt type is empty",
311+
promptType: new(string),
312+
expectedPromptTypeValue: "",
313+
},
314+
{
315+
name: "prompt type is set",
316+
promptType: &promptTypeLogin,
317+
expectedPromptTypeValue: "login",
318+
},
319+
}
320+
321+
ts := testSetup()
322+
defer ts.Close()
323+
324+
serviceAccountFilePath, err := tempServiceAccountKey()
325+
assert.Nil(t, err)
326+
327+
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath)
328+
329+
for _, test := range cases {
330+
t.Run(test.name, func(t *testing.T) {
331+
conn, err := newConnector(&Config{
332+
ClientID: "testClient",
333+
ClientSecret: "testSecret",
334+
RedirectURI: ts.URL + "/callback",
335+
Scopes: []string{"openid", "groups", "offline_access"},
336+
DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"},
337+
PromptType: test.promptType,
338+
})
339+
340+
assert.Nil(t, err)
341+
assert.Equal(t, test.expectedPromptTypeValue, conn.promptType)
342+
343+
loginURL, err := conn.LoginURL(connector.Scopes{OfflineAccess: true}, ts.URL+"/callback", "state")
344+
assert.Nil(t, err)
345+
346+
urlp, err := url.Parse(loginURL)
347+
assert.Nil(t, err)
348+
349+
assert.Equal(t, test.expectedPromptTypeValue, urlp.Query().Get("prompt"))
350+
})
351+
}
352+
}

connector/oidc/oidc.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ type Config struct {
7575

7676
UserNameKey string `json:"userNameKey"`
7777

78-
// PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent)
78+
// PromptType will be used for the prompt parameter (when offline_access, by default prompt=consent)
7979
PromptType *string `json:"promptType"`
8080

8181
// OverrideClaimMapping will be used to override the options defined in claimMappings.

0 commit comments

Comments
 (0)