diff --git a/coderd/userauth.go b/coderd/userauth.go index 8a80e92465ef4..8e3b02565ac94 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -65,6 +65,9 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) { } var selectedMembership *github.Membership for _, membership := range memberships { + if membership.GetState() != "active" { + continue + } for _, allowed := range api.GithubOAuth2Config.AllowOrganizations { if *membership.Organization.Login != allowed { continue diff --git a/coderd/userauth_test.go b/coderd/userauth_test.go index 5c411155904bb..e7b8286348b58 100644 --- a/coderd/userauth_test.go +++ b/coderd/userauth_test.go @@ -79,6 +79,10 @@ func TestUserAuthMethods(t *testing.T) { // nolint:bodyclose func TestUserOAuth2Github(t *testing.T) { t.Parallel() + + stateActive := "active" + statePending := "pending" + t.Run("NotInAllowedOrganization", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, &coderdtest.Options{ @@ -86,6 +90,7 @@ func TestUserOAuth2Github(t *testing.T) { OAuth2Config: &oauth2Config{}, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("kyle"), }, @@ -106,6 +111,7 @@ func TestUserOAuth2Github(t *testing.T) { OAuth2Config: &oauth2Config{}, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("coder"), }, @@ -132,6 +138,7 @@ func TestUserOAuth2Github(t *testing.T) { AllowOrganizations: []string{"coder"}, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("coder"), }, @@ -160,6 +167,7 @@ func TestUserOAuth2Github(t *testing.T) { AllowOrganizations: []string{"coder"}, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("coder"), }, @@ -188,6 +196,7 @@ func TestUserOAuth2Github(t *testing.T) { AllowOrganizations: []string{"coder"}, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("coder"), }, @@ -221,6 +230,7 @@ func TestUserOAuth2Github(t *testing.T) { AllowSignups: true, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("coder"), }, @@ -262,6 +272,7 @@ func TestUserOAuth2Github(t *testing.T) { OAuth2Config: &oauth2Config{}, ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { return []*github.Membership{{ + State: &stateActive, Organization: &github.Organization{ Login: github.String("coder"), }, @@ -287,6 +298,42 @@ func TestUserOAuth2Github(t *testing.T) { resp := oauth2Callback(t, client) require.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode) }) + t.Run("SignupFailedInactiveInOrg", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{ + GithubOAuth2Config: &coderd.GithubOAuth2Config{ + AllowSignups: true, + AllowOrganizations: []string{"coder"}, + AllowTeams: []coderd.GithubOAuth2Team{{"coder", "frontend"}}, + OAuth2Config: &oauth2Config{}, + ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { + return []*github.Membership{{ + State: &statePending, + Organization: &github.Organization{ + Login: github.String("coder"), + }, + }}, nil + }, + TeamMembership: func(ctx context.Context, client *http.Client, org, team, username string) (*github.Membership, error) { + return &github.Membership{}, nil + }, + AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) { + return &github.User{ + Login: github.String("kyle"), + }, nil + }, + ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) { + return []*github.UserEmail{{ + Email: github.String("kyle@coder.com"), + Verified: github.Bool(true), + Primary: github.Bool(true), + }}, nil + }, + }, + }) + resp := oauth2Callback(t, client) + require.Equal(t, http.StatusUnauthorized, resp.StatusCode) + }) } // nolint:bodyclose