From 4d8a3b39fe485a5f83c70617d594be01130c5b83 Mon Sep 17 00:00:00 2001 From: Marcus Weiner Date: Wed, 9 Feb 2022 13:49:33 +0100 Subject: [PATCH] Handle failed status code in provider requests (#313) --- api/provider/provider.go | 19 +++++++++++++++ api/provider/provider_test.go | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 api/provider/provider_test.go diff --git a/api/provider/provider.go b/api/provider/provider.go index c8513bc64..3a604036d 100644 --- a/api/provider/provider.go +++ b/api/provider/provider.go @@ -3,6 +3,8 @@ package provider import ( "context" "encoding/json" + "fmt" + "io/ioutil" "golang.org/x/oauth2" ) @@ -49,6 +51,15 @@ func chooseHost(base, defaultHost string) string { return base } +type RequestError struct { + code int + body string +} + +func (r *RequestError) Error() string { + return fmt.Sprintf("Request failed with status %d:\n%s", r.code, r.body) +} + func makeRequest(ctx context.Context, tok *oauth2.Token, g *oauth2.Config, url string, dst interface{}) error { client := g.Client(ctx, tok) res, err := client.Get(url) @@ -57,6 +68,14 @@ func makeRequest(ctx context.Context, tok *oauth2.Token, g *oauth2.Config, url s } defer res.Body.Close() + if res.StatusCode/100 != 2 { + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return err + } + return &RequestError{code: res.StatusCode, body: string(body)} + } + if err := json.NewDecoder(res.Body).Decode(dst); err != nil { return err } diff --git a/api/provider/provider_test.go b/api/provider/provider_test.go new file mode 100644 index 000000000..34db4315f --- /dev/null +++ b/api/provider/provider_test.go @@ -0,0 +1,44 @@ +package provider_test + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/netlify/gotrue/api/provider" + "github.com/netlify/gotrue/conf" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/oauth2" +) + +func TestGithubFail(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.WriteHeader(http.StatusTeapot) + fmt.Fprint(rw, "Something failed") + })) + t.Cleanup(srv.Close) + + gh, err := provider.NewGithubProvider(conf.OAuthProviderConfiguration{ + ClientID: "client-id", + Secret: "secret", + RedirectURI: "https://redirect.example.org/callback", + URL: srv.URL, + Enabled: true, + }) + require.NoError(t, err) + + user, err := gh.GetUserData(ctx, &oauth2.Token{ + AccessToken: "my-token", + Expiry: time.Now().Add(time.Minute), + }) + require.Error(t, err) + require.Nil(t, user) + assert.Equal(t, "Request failed with status 418:\nSomething failed", err.Error()) +}