func()

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