Skip to content

Commit adcf883

Browse files
authored
fix: Ensure GitHub OAuth2 users are active in organization (#4416)
1 parent e8e095e commit adcf883

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

coderd/userauth.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
6565
}
6666
var selectedMembership *github.Membership
6767
for _, membership := range memberships {
68+
if membership.GetState() != "active" {
69+
continue
70+
}
6871
for _, allowed := range api.GithubOAuth2Config.AllowOrganizations {
6972
if *membership.Organization.Login != allowed {
7073
continue

coderd/userauth_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,18 @@ func TestUserAuthMethods(t *testing.T) {
7979
// nolint:bodyclose
8080
func TestUserOAuth2Github(t *testing.T) {
8181
t.Parallel()
82+
83+
stateActive := "active"
84+
statePending := "pending"
85+
8286
t.Run("NotInAllowedOrganization", func(t *testing.T) {
8387
t.Parallel()
8488
client := coderdtest.New(t, &coderdtest.Options{
8589
GithubOAuth2Config: &coderd.GithubOAuth2Config{
8690
OAuth2Config: &oauth2Config{},
8791
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
8892
return []*github.Membership{{
93+
State: &stateActive,
8994
Organization: &github.Organization{
9095
Login: github.String("kyle"),
9196
},
@@ -106,6 +111,7 @@ func TestUserOAuth2Github(t *testing.T) {
106111
OAuth2Config: &oauth2Config{},
107112
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
108113
return []*github.Membership{{
114+
State: &stateActive,
109115
Organization: &github.Organization{
110116
Login: github.String("coder"),
111117
},
@@ -132,6 +138,7 @@ func TestUserOAuth2Github(t *testing.T) {
132138
AllowOrganizations: []string{"coder"},
133139
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
134140
return []*github.Membership{{
141+
State: &stateActive,
135142
Organization: &github.Organization{
136143
Login: github.String("coder"),
137144
},
@@ -160,6 +167,7 @@ func TestUserOAuth2Github(t *testing.T) {
160167
AllowOrganizations: []string{"coder"},
161168
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
162169
return []*github.Membership{{
170+
State: &stateActive,
163171
Organization: &github.Organization{
164172
Login: github.String("coder"),
165173
},
@@ -188,6 +196,7 @@ func TestUserOAuth2Github(t *testing.T) {
188196
AllowOrganizations: []string{"coder"},
189197
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
190198
return []*github.Membership{{
199+
State: &stateActive,
191200
Organization: &github.Organization{
192201
Login: github.String("coder"),
193202
},
@@ -221,6 +230,7 @@ func TestUserOAuth2Github(t *testing.T) {
221230
AllowSignups: true,
222231
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
223232
return []*github.Membership{{
233+
State: &stateActive,
224234
Organization: &github.Organization{
225235
Login: github.String("coder"),
226236
},
@@ -262,6 +272,7 @@ func TestUserOAuth2Github(t *testing.T) {
262272
OAuth2Config: &oauth2Config{},
263273
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
264274
return []*github.Membership{{
275+
State: &stateActive,
265276
Organization: &github.Organization{
266277
Login: github.String("coder"),
267278
},
@@ -287,6 +298,42 @@ func TestUserOAuth2Github(t *testing.T) {
287298
resp := oauth2Callback(t, client)
288299
require.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
289300
})
301+
t.Run("SignupFailedInactiveInOrg", func(t *testing.T) {
302+
t.Parallel()
303+
client := coderdtest.New(t, &coderdtest.Options{
304+
GithubOAuth2Config: &coderd.GithubOAuth2Config{
305+
AllowSignups: true,
306+
AllowOrganizations: []string{"coder"},
307+
AllowTeams: []coderd.GithubOAuth2Team{{"coder", "frontend"}},
308+
OAuth2Config: &oauth2Config{},
309+
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
310+
return []*github.Membership{{
311+
State: &statePending,
312+
Organization: &github.Organization{
313+
Login: github.String("coder"),
314+
},
315+
}}, nil
316+
},
317+
TeamMembership: func(ctx context.Context, client *http.Client, org, team, username string) (*github.Membership, error) {
318+
return &github.Membership{}, nil
319+
},
320+
AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) {
321+
return &github.User{
322+
Login: github.String("kyle"),
323+
}, nil
324+
},
325+
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
326+
return []*github.UserEmail{{
327+
Email: github.String("kyle@coder.com"),
328+
Verified: github.Bool(true),
329+
Primary: github.Bool(true),
330+
}}, nil
331+
},
332+
},
333+
})
334+
resp := oauth2Callback(t, client)
335+
require.Equal(t, http.StatusUnauthorized, resp.StatusCode)
336+
})
290337
}
291338

292339
// nolint:bodyclose

0 commit comments

Comments
 (0)