in auth/login.go [73:118]
func (a *GCRLoginAgent) PerformLogin() (*oauth2.Token, error) {
a.init()
conf := &oauth2.Config{
ClientID: config.GCRCredHelperClientID,
ClientSecret: config.GCRCredHelperClientNotSoSecret,
Scopes: config.GCRScopes,
Endpoint: config.GCROAuth2Endpoint,
}
verifier, challenge, method, err := codeChallengeParams()
state, err := makeRandString(16)
if err != nil {
return nil, fmt.Errorf("Unable to build random string: %v", err)
}
authCodeOpts := []oauth2.AuthCodeOption{
oauth2.AccessTypeOffline,
oauth2.SetAuthURLParam("code_challenge", challenge),
oauth2.SetAuthURLParam("code_challenge_method", method),
}
// Browser based auth is the only mechanism supported now.
// Attempt to receive the authorization code via redirect URL
ln, port, err := getListener()
if err != nil {
return nil, fmt.Errorf("Unable to open local listener: %v", err)
}
defer ln.Close()
// open a web browser and listen on the redirect URL port
conf.RedirectURL = fmt.Sprintf("http://localhost:%d", port)
url := conf.AuthCodeURL(state, authCodeOpts...)
err = a.OpenBrowser(url)
if err != nil {
return nil, fmt.Errorf("Unable to open browser: %v", err)
}
code, err := handleCodeResponse(ln, state)
if err != nil {
return nil, fmt.Errorf("Response was invalid: %v", err)
}
return conf.Exchange(
config.OAuthHTTPContext,
code,
oauth2.SetAuthURLParam("code_verifier", verifier))
}