mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
fix: Use membership endpoint to ensure user exists in team (#3129)
This was using the incorrect GitHub endpoint prior, which fetched a team by slug. Any user in a GitHub organization can view all teams, so this didn't block signups like intended. I've verified this API returns an error when the calling user is not a member of the team requested. Fixes #3105.
This commit is contained in:
@ -29,7 +29,7 @@ type GithubOAuth2Config struct {
|
||||
AuthenticatedUser func(ctx context.Context, client *http.Client) (*github.User, error)
|
||||
ListEmails func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error)
|
||||
ListOrganizationMemberships func(ctx context.Context, client *http.Client) ([]*github.Membership, error)
|
||||
Team func(ctx context.Context, client *http.Client, org, team string) (*github.Team, error)
|
||||
TeamMembership func(ctx context.Context, client *http.Client, org, team, username string) (*github.Membership, error)
|
||||
|
||||
AllowSignups bool
|
||||
AllowOrganizations []string
|
||||
@ -72,9 +72,18 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
ghUser, err := api.GithubOAuth2Config.AuthenticatedUser(r.Context(), oauthClient)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching authenticated Github user.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// The default if no teams are specified is to allow all.
|
||||
if len(api.GithubOAuth2Config.AllowTeams) > 0 {
|
||||
var allowedTeam *github.Team
|
||||
var allowedTeam *github.Membership
|
||||
for _, allowTeam := range api.GithubOAuth2Config.AllowTeams {
|
||||
if allowTeam.Organization != *selectedMembership.Organization.Login {
|
||||
// This needs to continue because multiple organizations
|
||||
@ -82,7 +91,7 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
|
||||
continue
|
||||
}
|
||||
|
||||
allowedTeam, err = api.GithubOAuth2Config.Team(r.Context(), oauthClient, allowTeam.Organization, allowTeam.Slug)
|
||||
allowedTeam, err = api.GithubOAuth2Config.TeamMembership(r.Context(), oauthClient, allowTeam.Organization, allowTeam.Slug, *ghUser.Login)
|
||||
// The calling user may not have permission to the requested team!
|
||||
if err != nil {
|
||||
continue
|
||||
@ -151,14 +160,6 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
|
||||
// email to organization.
|
||||
organizationID = organizations[0].ID
|
||||
}
|
||||
ghUser, err := api.GithubOAuth2Config.AuthenticatedUser(r.Context(), oauthClient)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching authenticated Github user.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
var verifiedEmail *github.UserEmail
|
||||
for _, email := range emails {
|
||||
if !email.GetPrimary() || !email.GetVerified() {
|
||||
|
@ -88,7 +88,12 @@ func TestUserOAuth2Github(t *testing.T) {
|
||||
},
|
||||
}}, nil
|
||||
},
|
||||
Team: func(ctx context.Context, client *http.Client, org, team string) (*github.Team, error) {
|
||||
AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) {
|
||||
return &github.User{
|
||||
Login: github.String("kyle"),
|
||||
}, nil
|
||||
},
|
||||
TeamMembership: func(ctx context.Context, client *http.Client, org, team, username string) (*github.Membership, error) {
|
||||
return nil, xerrors.New("no perms")
|
||||
},
|
||||
},
|
||||
@ -222,8 +227,8 @@ func TestUserOAuth2Github(t *testing.T) {
|
||||
},
|
||||
}}, nil
|
||||
},
|
||||
Team: func(ctx context.Context, client *http.Client, org, team string) (*github.Team, error) {
|
||||
return &github.Team{}, 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{
|
||||
|
Reference in New Issue
Block a user