func()

in pkg/provider/onelogin/onelogin.go [89:166]


func (c *Client) Authenticate(loginDetails *creds.LoginDetails) (string, error) {
	providerURL, err := url.Parse(loginDetails.URL)
	if err != nil {
		return "", errors.Wrap(err, "error building providerURL")
	}
	host := providerURL.Host

	logger.Debug("Generating OneLogin access token")
	// request oAuth token required for working with OneLogin APIs
	oauthToken, err := generateToken(c, loginDetails, host)
	if err != nil {
		return "", errors.Wrap(err, "failed to generate oauth token")
	}

	logger.Debug("Retrieved OneLogin OAuth token:", oauthToken)

	authReq := AuthRequest{Username: loginDetails.Username, Password: loginDetails.Password, AppID: c.AppID, Subdomain: c.Subdomain}
	var authBody bytes.Buffer
	err = json.NewEncoder(&authBody).Encode(authReq)
	if err != nil {
		return "", errors.Wrap(err, "error encoding authreq")
	}

	authSubmitURL := fmt.Sprintf("https://%s/api/2/saml_assertion", host)

	req, err := http.NewRequest("POST", authSubmitURL, &authBody)
	if err != nil {
		return "", errors.Wrap(err, "error building authentication request")
	}

	addContentHeaders(req)
	addAuthHeader(req, oauthToken)

	logger.Debug("Requesting SAML Assertion")

	// request the SAML assertion. For more details check https://developers.onelogin.com/api-docs/2/saml-assertions/generate-saml-assertion
	res, err := c.Client.Do(req)
	if err != nil {
		return "", errors.Wrap(err, "error retrieving auth response")
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", errors.Wrap(err, "error retrieving body from response")
	}

	resp := string(body)

	logger.Debug("SAML Assertion response code:", res.StatusCode)
	logger.Debug("SAML Assertion response body:", resp)

	authMessage := gjson.Get(resp, "message").String()
	if res.StatusCode != 200 {
		return "", fmt.Errorf("HTTP %v: %s", res.StatusCode, authMessage)
	}

	authData := gjson.Get(resp, "data")
	var samlAssertion string
	switch authMessage {
	// MFA not required
	case MessageSuccess:
		if authData.IsArray() {
			return "", errors.New("invalid SAML assertion returned")
		}
		samlAssertion = authData.String()
	case MessageMFARequired:
		logger.Debug("Verifying MFA")
		samlAssertion, err = verifyMFA(c, oauthToken, c.AppID, resp)
		if err != nil {
			return "", errors.Wrap(err, "error verifying MFA")
		}
	default:
		return "", errors.New("unexpected SAML assertion response")
	}

	return samlAssertion, nil
}