in pkg/provider/googleapps/googleapps.go [468:526]
func (kc *Client) loadAlternateChallengePage(submitURL string, referer string, authForm url.Values, loginDetails *creds.LoginDetails) (*goquery.Document, error) {
req, err := http.NewRequest("POST", submitURL, strings.NewReader(authForm.Encode()))
if err != nil {
return nil, errors.Wrap(err, "error retrieving login form")
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept-Language", "en-US")
req.Header.Set("Content-Language", "en-US")
req.Header.Set("Referer", referer)
res, err := kc.client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to make request to login form")
}
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
return nil, errors.Wrap(err, "error parsing login page html document")
}
doc.Url, err = url.Parse(submitURL)
if err != nil {
return nil, errors.Wrap(err, "failed to define URL for html doc")
}
var challengeEntry string
doc.Find("form[data-challengeentry]").EachWithBreak(func(i int, s *goquery.Selection) bool {
action, ok := s.Attr("action")
if !ok {
return true
}
if strings.Contains(action, "challenge/totp/") ||
strings.Contains(action, "challenge/ipp/") ||
strings.Contains(action, "challenge/az/") ||
strings.Contains(action, "challenge/skotp/") {
challengeEntry, _ = s.Attr("data-challengeentry")
return false
}
return true
})
if challengeEntry == "" {
return nil, errors.New("unable to find supported second factor")
}
query := fmt.Sprintf(`[data-challengeentry="%s"]`, challengeEntry)
responseForm, newActionURL, err := extractInputsByFormQuery(doc, query)
if err != nil {
return nil, errors.Wrap(err, "unable to extract challenge form")
}
return kc.loadChallengePage(newActionURL, submitURL, responseForm, loginDetails)
}