func()

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))
}