func()

in pkg/provider/aad/aad.go [436:501]


func (ac *Client) processMfa(mfas []userProof, convergedResponse *ConvergedResponse) (*http.Response, error) {
	var res *http.Response
	var err error
	var mfaResp mfaResponse

	if len(mfas) == 0 {
		return res, fmt.Errorf("MFA not found")
	}

	mfaResp, err = ac.processMfaBeginAuth(mfas, convergedResponse)
	if err != nil {
		return res, errors.Wrap(err, "error processing MFA BeginAuth")
	}

	for i := 0; ; i++ {
		mfaReq := mfaRequest{
			AuthMethodID: mfaResp.AuthMethodID,
			Method:       "EndAuth",
			Ctx:          mfaResp.Ctx,
			FlowToken:    mfaResp.FlowToken,
			SessionID:    mfaResp.SessionID,
		}
		if mfaReq.AuthMethodID == "PhoneAppOTP" || mfaReq.AuthMethodID == "OneWaySMS" {
			verifyCode := prompter.StringRequired("Enter verification code")
			mfaReq.AdditionalAuthData = verifyCode
		}
		if mfaReq.AuthMethodID == "PhoneAppNotification" && i == 0 {
			if mfaResp.Entropy == 0 {
				prompter.Display("Phone approval required.")
			} else {
				prompter.Display(fmt.Sprintf("Phone approval required. Entropy is: %d", mfaResp.Entropy))
			}
		}

		mfaResp, err = ac.processMfaEndAuth(mfaReq, convergedResponse)
		if err != nil {
			return res, errors.Wrap(err, "error processing MFA EndAuth")
		}

		if mfaResp.ErrCode != 0 {
			return res, fmt.Errorf("error processing MFA, errcode: %d, message: %v", mfaResp.ErrCode, mfaResp.Message)
		}

		if mfaResp.Success {
			break
		}
		if !mfaResp.Retry {
			break
		}

		// if mfaResp.Retry == true then
		// must exist convergedResponse.OPerAuthPollingInterval[mfaResp.AuthMethodID]
		time.Sleep(time.Duration(convergedResponse.OPerAuthPollingInterval[mfaResp.AuthMethodID]) * time.Second)
	}

	if !mfaResp.Success {
		return res, fmt.Errorf("error processing MFA")
	}

	res, err = ac.processMfaAuth(mfaResp, convergedResponse)
	if err != nil {
		return res, errors.Wrap(err, "error processing MFA ProcessAuth")
	}

	return res, nil
}