in pkg/provider/adfs/adfs.go [56:145]
func (ac *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) {
var authSubmitURL string
var samlAssertion string
var instructions string
alibabacloudURN := url.QueryEscape(ac.idpAccount.AlibabaCloudURN)
adfsURL := fmt.Sprintf("%s/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=%s", loginDetails.URL, alibabacloudURN)
mfaToken := loginDetails.MFAToken
doc, err := ac.get(adfsURL)
if err != nil {
return "", errors.Wrap(err, "failed to get adfs page")
}
authForm := url.Values{}
doc.Find("input").Each(func(i int, s *goquery.Selection) {
updateFormData(authForm, s, loginDetails)
})
doc.Find("form").Each(func(i int, s *goquery.Selection) {
action, ok := s.Attr("action")
if !ok {
return
}
authSubmitURL = action
})
if authSubmitURL == "" {
return samlAssertion, fmt.Errorf("unable to locate IDP authentication form submit URL")
}
doc, err = ac.submit(authSubmitURL, authForm)
if err != nil {
return samlAssertion, errors.Wrap(err, "failed to submit adfs auth form")
}
for {
responseType, samlAssertion, err := checkResponse(doc)
switch responseType {
case SAML_RESPONSE:
return samlAssertion, err
case MFA_PROMPT:
otpForm := url.Values{}
if mfaToken == "" {
mfaToken = prompter.RequestSecurityCode("000000")
}
doc.Find("input").Each(func(i int, s *goquery.Selection) {
updateOTPFormData(otpForm, s, mfaToken)
})
doc, err = ac.submit(authSubmitURL, otpForm)
if err != nil {
return samlAssertion, errors.Wrap(err, "error retrieving mfa form results")
}
mfaToken = ""
case AZURE_MFA_SERVER_WAIT:
fallthrough
case AZURE_MFA_WAIT:
azureForm := url.Values{}
doc.Find("input").Each(func(i int, s *goquery.Selection) {
updatePassthroughFormData(azureForm, s)
})
sel := doc.Find("p#instructions")
if sel.Index() != -1 {
if instructions != sel.Text() {
instructions = sel.Text()
log.Println(instructions)
}
}
time.Sleep(1 * time.Second)
doc, err = ac.submit(authSubmitURL, azureForm)
if err != nil {
return samlAssertion, errors.Wrap(err, "error retrieving mfa form results")
}
if responseType == AZURE_MFA_SERVER_WAIT {
sel := doc.Find("label#errorText")
if sel.Index() != -1 {
return samlAssertion, errors.New(sel.Text())
}
}
case UNKNOWN:
return samlAssertion, errors.New("unable to classify response from auth server")
}
}
}