Skip to content

Commit b888145

Browse files
committed
backend tests
1 parent 286abb7 commit b888145

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

coderd/userauth_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/prometheus/client_golang/prometheus"
2323
"github.com/stretchr/testify/assert"
2424
"github.com/stretchr/testify/require"
25+
"golang.org/x/oauth2"
2526
"golang.org/x/xerrors"
2627

2728
"cdr.dev/slog"
@@ -882,6 +883,92 @@ func TestUserOAuth2Github(t *testing.T) {
882883
require.Equal(t, user.ID, userID, "user_id is different, a new user was likely created")
883884
require.Equal(t, user.Email, newEmail)
884885
})
886+
t.Run("DeviceFlow", func(t *testing.T) {
887+
t.Parallel()
888+
client := coderdtest.New(t, &coderdtest.Options{
889+
GithubOAuth2Config: &coderd.GithubOAuth2Config{
890+
OAuth2Config: &testutil.OAuth2Config{},
891+
AllowOrganizations: []string{"coder"},
892+
AllowSignups: true,
893+
ListOrganizationMemberships: func(_ context.Context, _ *http.Client) ([]*github.Membership, error) {
894+
return []*github.Membership{{
895+
State: &stateActive,
896+
Organization: &github.Organization{
897+
Login: github.String("coder"),
898+
},
899+
}}, nil
900+
},
901+
AuthenticatedUser: func(_ context.Context, _ *http.Client) (*github.User, error) {
902+
return &github.User{
903+
ID: github.Int64(100),
904+
Login: github.String("testuser"),
905+
Name: github.String("The Right Honorable Sir Test McUser"),
906+
}, nil
907+
},
908+
ListEmails: func(_ context.Context, _ *http.Client) ([]*github.UserEmail, error) {
909+
return []*github.UserEmail{{
910+
Email: github.String("testuser@coder.com"),
911+
Verified: github.Bool(true),
912+
Primary: github.Bool(true),
913+
}}, nil
914+
},
915+
DeviceFlowEnabled: true,
916+
ExchangeDeviceCode: func(_ context.Context, _ string) (*oauth2.Token, error) {
917+
return &oauth2.Token{
918+
AccessToken: "access_token",
919+
RefreshToken: "refresh_token",
920+
Expiry: time.Now().Add(time.Hour),
921+
}, nil
922+
},
923+
AuthorizeDevice: func(_ context.Context) (*codersdk.ExternalAuthDevice, error) {
924+
return &codersdk.ExternalAuthDevice{
925+
DeviceCode: "device_code",
926+
UserCode: "user_code",
927+
}, nil
928+
},
929+
},
930+
})
931+
client.HTTPClient.CheckRedirect = func(*http.Request, []*http.Request) error {
932+
return http.ErrUseLastResponse
933+
}
934+
935+
// Ensure that we redirect to the device login page when the user is not logged in.
936+
oauthURL, err := client.URL.Parse("/api/v2/users/oauth2/github/callback")
937+
require.NoError(t, err)
938+
939+
req, err := http.NewRequestWithContext(context.Background(), "GET", oauthURL.String(), nil)
940+
941+
require.NoError(t, err)
942+
res, err := client.HTTPClient.Do(req)
943+
require.NoError(t, err)
944+
defer res.Body.Close()
945+
946+
require.Equal(t, http.StatusTemporaryRedirect, res.StatusCode)
947+
location, err := res.Location()
948+
require.NoError(t, err)
949+
require.Equal(t, "/login/device", location.Path)
950+
query := location.Query()
951+
require.NotEmpty(t, query.Get("state"))
952+
953+
// Ensure that we return a JSON response when the code is successfully exchanged.
954+
oauthURL, err = client.URL.Parse("/api/v2/users/oauth2/github/callback?code=hey&state=somestate")
955+
require.NoError(t, err)
956+
957+
req, err = http.NewRequestWithContext(context.Background(), "GET", oauthURL.String(), nil)
958+
req.AddCookie(&http.Cookie{
959+
Name: "oauth_state",
960+
Value: "somestate",
961+
})
962+
require.NoError(t, err)
963+
res, err = client.HTTPClient.Do(req)
964+
require.NoError(t, err)
965+
defer res.Body.Close()
966+
967+
require.Equal(t, http.StatusOK, res.StatusCode)
968+
var resp codersdk.OAuth2DeviceFlowCallbackResponse
969+
require.NoError(t, json.NewDecoder(res.Body).Decode(&resp))
970+
require.Equal(t, "/", resp.RedirectURL)
971+
})
885972
}
886973

887974
// nolint:bodyclose

0 commit comments

Comments
 (0)