Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f62e1ed

Browse files
authored
feat: Add support for GitHub Enterprise authentication (#3422)
This was manually tested with GitHub Enterprise v3.6.0-rc1.
1 parent 7bdb8ff commit f62e1ed

File tree

3 files changed

+88
-7
lines changed

3 files changed

+88
-7
lines changed

cli/server.go

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ func server() *cobra.Command {
8787
oauth2GithubAllowedOrganizations []string
8888
oauth2GithubAllowedTeams []string
8989
oauth2GithubAllowSignups bool
90+
oauth2GithubEnterpriseBaseURL string
9091
oidcAllowSignups bool
9192
oidcClientID string
9293
oidcClientSecret string
@@ -286,7 +287,7 @@ func server() *cobra.Command {
286287
}
287288

288289
if oauth2GithubClientSecret != "" {
289-
options.GithubOAuth2Config, err = configureGithubOAuth2(accessURLParsed, oauth2GithubClientID, oauth2GithubClientSecret, oauth2GithubAllowSignups, oauth2GithubAllowedOrganizations, oauth2GithubAllowedTeams)
290+
options.GithubOAuth2Config, err = configureGithubOAuth2(accessURLParsed, oauth2GithubClientID, oauth2GithubClientSecret, oauth2GithubAllowSignups, oauth2GithubAllowedOrganizations, oauth2GithubAllowedTeams, oauth2GithubEnterpriseBaseURL)
290291
if err != nil {
291292
return xerrors.Errorf("configure github oauth2: %w", err)
292293
}
@@ -695,6 +696,8 @@ func server() *cobra.Command {
695696
"Specifies teams inside organizations the user must be a member of to authenticate with GitHub. Formatted as: <organization-name>/<team-slug>.")
696697
cliflag.BoolVarP(root.Flags(), &oauth2GithubAllowSignups, "oauth2-github-allow-signups", "", "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS", false,
697698
"Specifies whether new users can sign up with GitHub.")
699+
cliflag.StringVarP(root.Flags(), &oauth2GithubEnterpriseBaseURL, "oauth2-github-enterprise-base-url", "", "CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL", "",
700+
"Specifies the base URL of a GitHub Enterprise instance to use for oauth2.")
698701
cliflag.BoolVarP(root.Flags(), &oidcAllowSignups, "oidc-allow-signups", "", "CODER_OIDC_ALLOW_SIGNUPS", true,
699702
"Specifies whether new users can sign up with OIDC.")
700703
cliflag.StringVarP(root.Flags(), &oidcClientID, "oidc-client-id", "", "CODER_OIDC_CLIENT_ID", "",
@@ -972,7 +975,7 @@ func configureTLS(listener net.Listener, tlsMinVersion, tlsClientAuth, tlsCertFi
972975
return tls.NewListener(listener, tlsConfig), nil
973976
}
974977

975-
func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, allowSignups bool, allowOrgs []string, rawTeams []string) (*coderd.GithubOAuth2Config, error) {
978+
func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, allowSignups bool, allowOrgs []string, rawTeams []string, enterpriseBaseURL string) (*coderd.GithubOAuth2Config, error) {
976979
redirectURL, err := accessURL.Parse("/api/v2/users/oauth2/github/callback")
977980
if err != nil {
978981
return nil, xerrors.Errorf("parse github oauth callback url: %w", err)
@@ -988,11 +991,38 @@ func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, al
988991
Slug: parts[1],
989992
})
990993
}
994+
createClient := func(client *http.Client) (*github.Client, error) {
995+
if enterpriseBaseURL != "" {
996+
return github.NewEnterpriseClient(enterpriseBaseURL, "", client)
997+
}
998+
return github.NewClient(client), nil
999+
}
1000+
1001+
endpoint := xgithub.Endpoint
1002+
if enterpriseBaseURL != "" {
1003+
enterpriseURL, err := url.Parse(enterpriseBaseURL)
1004+
if err != nil {
1005+
return nil, xerrors.Errorf("parse enterprise base url: %w", err)
1006+
}
1007+
authURL, err := enterpriseURL.Parse("/login/oauth/authorize")
1008+
if err != nil {
1009+
return nil, xerrors.Errorf("parse enterprise auth url: %w", err)
1010+
}
1011+
tokenURL, err := enterpriseURL.Parse("/login/oauth/access_token")
1012+
if err != nil {
1013+
return nil, xerrors.Errorf("parse enterprise token url: %w", err)
1014+
}
1015+
endpoint = oauth2.Endpoint{
1016+
AuthURL: authURL.String(),
1017+
TokenURL: tokenURL.String(),
1018+
}
1019+
}
1020+
9911021
return &coderd.GithubOAuth2Config{
9921022
OAuth2Config: &oauth2.Config{
9931023
ClientID: clientID,
9941024
ClientSecret: clientSecret,
995-
Endpoint: xgithub.Endpoint,
1025+
Endpoint: endpoint,
9961026
RedirectURL: redirectURL.String(),
9971027
Scopes: []string{
9981028
"read:user",
@@ -1004,15 +1034,27 @@ func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, al
10041034
AllowOrganizations: allowOrgs,
10051035
AllowTeams: allowTeams,
10061036
AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) {
1007-
user, _, err := github.NewClient(client).Users.Get(ctx, "")
1037+
api, err := createClient(client)
1038+
if err != nil {
1039+
return nil, err
1040+
}
1041+
user, _, err := api.Users.Get(ctx, "")
10081042
return user, err
10091043
},
10101044
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
1011-
emails, _, err := github.NewClient(client).Users.ListEmails(ctx, &github.ListOptions{})
1045+
api, err := createClient(client)
1046+
if err != nil {
1047+
return nil, err
1048+
}
1049+
emails, _, err := api.Users.ListEmails(ctx, &github.ListOptions{})
10121050
return emails, err
10131051
},
10141052
ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) {
1015-
memberships, _, err := github.NewClient(client).Organizations.ListOrgMemberships(ctx, &github.ListOrgMembershipsOptions{
1053+
api, err := createClient(client)
1054+
if err != nil {
1055+
return nil, err
1056+
}
1057+
memberships, _, err := api.Organizations.ListOrgMemberships(ctx, &github.ListOrgMembershipsOptions{
10161058
State: "active",
10171059
ListOptions: github.ListOptions{
10181060
PerPage: 100,
@@ -1021,7 +1063,11 @@ func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, al
10211063
return memberships, err
10221064
},
10231065
TeamMembership: func(ctx context.Context, client *http.Client, org, teamSlug, username string) (*github.Membership, error) {
1024-
team, _, err := github.NewClient(client).Teams.GetTeamMembershipBySlug(ctx, org, teamSlug, username)
1066+
api, err := createClient(client)
1067+
if err != nil {
1068+
return nil, err
1069+
}
1070+
team, _, err := api.Teams.GetTeamMembershipBySlug(ctx, org, teamSlug, username)
10251071
return team, err
10261072
},
10271073
}, nil

cli/server_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,39 @@ func TestServer(t *testing.T) {
436436
cancelFunc()
437437
<-serverErr
438438
})
439+
t.Run("GitHubOAuth", func(t *testing.T) {
440+
t.Parallel()
441+
ctx, cancelFunc := context.WithCancel(context.Background())
442+
defer cancelFunc()
443+
444+
fakeRedirect := "https://fake-url.com"
445+
root, cfg := clitest.New(t,
446+
"server",
447+
"--in-memory",
448+
"--address", ":0",
449+
"--oauth2-github-client-id", "fake",
450+
"--oauth2-github-client-secret", "fake",
451+
"--oauth2-github-enterprise-base-url", fakeRedirect,
452+
)
453+
serverErr := make(chan error, 1)
454+
go func() {
455+
serverErr <- root.ExecuteContext(ctx)
456+
}()
457+
accessURL := waitAccessURL(t, cfg)
458+
client := codersdk.New(accessURL)
459+
client.HTTPClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
460+
return http.ErrUseLastResponse
461+
}
462+
githubURL, err := accessURL.Parse("/api/v2/users/oauth2/github")
463+
require.NoError(t, err)
464+
res, err := client.HTTPClient.Get(githubURL.String())
465+
require.NoError(t, err)
466+
fakeURL, err := res.Location()
467+
require.NoError(t, err)
468+
require.True(t, strings.HasPrefix(fakeURL.String(), fakeRedirect), fakeURL.String())
469+
cancelFunc()
470+
<-serverErr
471+
})
439472
}
440473

441474
func generateTLSCertificate(t testing.TB) (certPath, keyPath string) {

docs/install/auth.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ server:
2525
coder server --oauth2-github-allow-signups=true --oauth2-github-allowed-orgs="your-org" --oauth2-github-client-id="8d1...e05" --oauth2-github-client-secret="57ebc9...02c24c"
2626
```
2727

28+
> For GitHub Enterprise support, specify the `--oauth2-github-enterprise-base-url` flag.
29+
2830
Alternatively, if you are running Coder as a system service, you can achieve the
2931
same result as the command above by adding the following environment variables
3032
to the `/etc/coder.d/coder.env` file:

0 commit comments

Comments
 (0)