From 21c833b742d7694e52fe04fd784d6ccd874af6ef Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 20 Sep 2021 09:20:41 +0200 Subject: [PATCH] add support for MFA via callback --- api/api.go | 19 +++++++++++++++++++ api/client.go | 3 +++ 2 files changed, 22 insertions(+) diff --git a/api/api.go b/api/api.go index 15225d8..ff57891 100644 --- a/api/api.go +++ b/api/api.go @@ -32,6 +32,8 @@ func (c *Client) DoCustomRequest(ctx context.Context, method, path, version stri // DoCustomRequestAndReturnRawResponse Executes a Custom Request and returns a APIResponse and the Raw HTTP Response func (c *Client) DoCustomRequestAndReturnRawResponse(ctx context.Context, method, path, version string, body interface{}, opts interface{}) (*http.Response, *APIResponse, error) { + firstTime := true +start: u, err := addOptions(path, version, opts) if err != nil { return nil, nil, fmt.Errorf("Adding Request Options: %w", err) @@ -51,6 +53,23 @@ func (c *Client) DoCustomRequestAndReturnRawResponse(ctx context.Context, method if res.Header.Status == "success" { return r, &res, nil } else if res.Header.Status == "error" { + if res.Header.Code == 403 && res.Header.Message == "MFA authentication is required." { + if !firstTime { + // if we are here this probably means that the MFA callback is broken, to prevent a infinit loop lets error here + return r, &res, fmt.Errorf("Got MFA challenge twice in a row, is your MFA Callback broken? Bailing to prevent loop...:") + } + if c.mfaCallback != nil { + err = c.mfaCallback(c, &res) + if err != nil { + return r, &res, fmt.Errorf("MFA Callback: %w", err) + } + // ok, we got the MFA challange and the callback presumably handeld it so we can retry the original request + firstTime = false + goto start + } else { + return r, &res, fmt.Errorf("Got MFA Challange but the MFA callback is not defined") + } + } return r, &res, fmt.Errorf("%w: Message: %v, Body: %v", ErrAPIResponseErrorStatusCode, res.Header.Message, string(res.Body)) } else { return r, &res, fmt.Errorf("%w: Message: %v, Body: %v", ErrAPIResponseUnknownStatusCode, res.Header.Message, string(res.Body)) diff --git a/api/client.go b/api/client.go index 210e8eb..26bd2d7 100644 --- a/api/client.go +++ b/api/client.go @@ -29,6 +29,8 @@ type Client struct { userPublicKey string userID string + mfaCallback func(c *Client, res *APIResponse) error + // Enable Debug Logging Debug bool } @@ -147,6 +149,7 @@ func (c *Client) do(ctx context.Context, req *http.Request, v *APIResponse) (*ht if err != nil { return resp, fmt.Errorf("Unable to Parse JSON API Response with HTTP Status Code %v: %w", resp.StatusCode, err) } + return resp, nil }