Skip to content

Commit fa439f7

Browse files
authored
Merge pull request #325 from coufalja/google-hd
Added hosted domain (hd) parameter to google provider
2 parents 5d315f4 + 61c1ad3 commit fa439f7

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

providers/google/google.go

+21-15
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
3232

3333
// Provider is the implementation of `goth.Provider` for accessing Google.
3434
type Provider struct {
35-
ClientKey string
36-
Secret string
37-
CallbackURL string
38-
HTTPClient *http.Client
39-
config *oauth2.Config
40-
prompt oauth2.AuthCodeOption
41-
providerName string
35+
ClientKey string
36+
Secret string
37+
CallbackURL string
38+
HTTPClient *http.Client
39+
config *oauth2.Config
40+
authCodeOptions []oauth2.AuthCodeOption
41+
providerName string
4242
}
4343

4444
// Name is the name used to retrieve this provider later.
@@ -61,11 +61,7 @@ func (p *Provider) Debug(debug bool) {}
6161

6262
// BeginAuth asks Google for an authentication endpoint.
6363
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
64-
var opts []oauth2.AuthCodeOption
65-
if p.prompt != nil {
66-
opts = append(opts, p.prompt)
67-
}
68-
url := p.config.AuthCodeURL(state, opts...)
64+
url := p.config.AuthCodeURL(state, p.authCodeOptions...)
6965
session := &Session{
7066
AuthURL: url,
7167
}
@@ -152,12 +148,12 @@ func newConfig(provider *Provider, scopes []string) *oauth2.Config {
152148
return c
153149
}
154150

155-
//RefreshTokenAvailable refresh token is provided by auth provider or not
151+
// RefreshTokenAvailable refresh token is provided by auth provider or not
156152
func (p *Provider) RefreshTokenAvailable() bool {
157153
return true
158154
}
159155

160-
//RefreshToken get new access token based on the refresh token
156+
// RefreshToken get new access token based on the refresh token
161157
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
162158
token := &oauth2.Token{RefreshToken: refreshToken}
163159
ts := p.config.TokenSource(goth.ContextForClient(p.Client()), token)
@@ -176,5 +172,15 @@ func (p *Provider) SetPrompt(prompt ...string) {
176172
if len(prompt) == 0 {
177173
return
178174
}
179-
p.prompt = oauth2.SetAuthURLParam("prompt", strings.Join(prompt, " "))
175+
p.authCodeOptions = append(p.authCodeOptions, oauth2.SetAuthURLParam("prompt", strings.Join(prompt, " ")))
176+
}
177+
178+
// SetHostedDomain sets the hd parameter for google OAuth call.
179+
// Use this to force user to pick user from specific hosted domain.
180+
// See https://developers.google.com/identity/protocols/oauth2/openid-connect#hd-param
181+
func (p *Provider) SetHostedDomain(hd string) {
182+
if hd == "" {
183+
return
184+
}
185+
p.authCodeOptions = append(p.authCodeOptions, oauth2.SetAuthURLParam("hd", hd))
180186
}

providers/google/google_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,25 @@ func Test_BeginAuthWithPrompt(t *testing.T) {
5353
a.Contains(s.AuthURL, "prompt=test+prompts")
5454
}
5555

56+
func Test_BeginAuthWithHostedDomain(t *testing.T) {
57+
// This exists because there was a panic caused by the oauth2 package when
58+
// the AuthCodeOption passed was nil. This test uses it, Test_BeginAuth does
59+
// not, to ensure both cases are covered.
60+
t.Parallel()
61+
a := assert.New(t)
62+
63+
provider := googleProvider()
64+
provider.SetHostedDomain("example.com")
65+
session, err := provider.BeginAuth("test_state")
66+
s := session.(*google.Session)
67+
a.NoError(err)
68+
a.Contains(s.AuthURL, "accounts.google.com/o/oauth2/auth")
69+
a.Contains(s.AuthURL, fmt.Sprintf("client_id=%s", os.Getenv("GOOGLE_KEY")))
70+
a.Contains(s.AuthURL, "state=test_state")
71+
a.Contains(s.AuthURL, "scope=email")
72+
a.Contains(s.AuthURL, "hd=example.com")
73+
}
74+
5675
func Test_Implements_Provider(t *testing.T) {
5776
t.Parallel()
5877
a := assert.New(t)

0 commit comments

Comments
 (0)