Browse Source

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

Signed-off-by: abhisek <abhisek.datta@gmail.com>
Signed-off-by: Maksim Nabokikh <max.nabokih@gmail.com>
Co-authored-by: Maksim Nabokikh <max.nabokih@gmail.com>
pull/2039/merge
Abhisek Datta 2 years ago committed by GitHub
parent
commit
677ab36020
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      connector/google/google.go
  2. 60
      connector/google/google_test.go
  3. 2
      connector/oidc/oidc.go

14
connector/google/google.go

@ -58,6 +58,10 @@ type Config struct {
// If this field is true, fetch direct group membership and transitive group membership
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.
@ -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
return &googleConnector{
redirectURI: c.RedirectURI,
@ -128,6 +137,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
domainToAdminEmail: c.DomainToAdminEmail,
fetchTransitiveGroupMembership: c.FetchTransitiveGroupMembership,
adminSrv: adminSrv,
promptType: promptType,
}, nil
}
@ -148,6 +158,7 @@ type googleConnector struct {
domainToAdminEmail map[string]string
fetchTransitiveGroupMembership bool
adminSrv map[string]*admin.Service
promptType string
}
func (c *googleConnector) Close() error {
@ -170,8 +181,9 @@ func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string
}
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
}

60
connector/google/google_test.go

@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
@ -13,6 +14,8 @@ import (
"github.com/stretchr/testify/assert"
admin "google.golang.org/api/admin/directory/v1"
"google.golang.org/api/option"
"github.com/dexidp/dex/connector"
)
var (
@ -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"))
})
}
}

2
connector/oidc/oidc.go

@ -75,7 +75,7 @@ type Config struct {
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"`
// OverrideClaimMapping will be used to override the options defined in claimMappings.

Loading…
Cancel
Save