From 43f579e48aa527c643f454675c5fc6daca80fb14 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 10 Jan 2024 10:02:25 -0600 Subject: [PATCH 1/2] fix: return a more sophisticated error for device failure on 429 --- coderd/externalauth/externalauth.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/coderd/externalauth/externalauth.go b/coderd/externalauth/externalauth.go index db08268bf75d3..64e8c9c5c21e1 100644 --- a/coderd/externalauth/externalauth.go +++ b/coderd/externalauth/externalauth.go @@ -321,7 +321,14 @@ func (c *DeviceAuth) AuthorizeDevice(ctx context.Context) (*codersdk.ExternalAut } err = json.NewDecoder(resp.Body).Decode(&r) if err != nil { - return nil, err + // Some status codes do not return json payloads, and we should + // return a better error. + switch resp.StatusCode { + case http.StatusTooManyRequests: + return nil, fmt.Errorf("rate limit hit, unable to authorize device. please try again later") + default: + return nil, err + } } if r.ErrorDescription != "" { return nil, xerrors.New(r.ErrorDescription) From 0ccf9c592fc7e9d00e9a7e9e905914f332eb25bb Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 10 Jan 2024 10:06:18 -0600 Subject: [PATCH 2/2] Add unit test --- coderd/externalauth_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/coderd/externalauth_test.go b/coderd/externalauth_test.go index 1d0b06bbc0506..e109405c4e640 100644 --- a/coderd/externalauth_test.go +++ b/coderd/externalauth_test.go @@ -279,6 +279,28 @@ func TestExternalAuthDevice(t *testing.T) { require.NoError(t, err) require.True(t, auth.Authenticated) }) + t.Run("TooManyRequests", func(t *testing.T) { + t.Parallel() + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusTooManyRequests) + // Github returns an html payload for this error. + _, _ = w.Write([]byte(`Please wait a few minutes before you try again`)) + })) + defer srv.Close() + client := coderdtest.New(t, &coderdtest.Options{ + ExternalAuthConfigs: []*externalauth.Config{{ + ID: "test", + DeviceAuth: &externalauth.DeviceAuth{ + ClientID: "test", + CodeURL: srv.URL, + Scopes: []string{"repo"}, + }, + }}, + }) + coderdtest.CreateFirstUser(t, client) + _, err := client.ExternalAuthDeviceByID(context.Background(), "test") + require.ErrorContains(t, err, "rate limit hit") + }) } // nolint:bodyclose