@@ -18,8 +18,11 @@ import (
18
18
19
19
"github.com/briandowns/spinner"
20
20
"github.com/coreos/go-systemd/daemon"
21
+ "github.com/google/go-github/v43/github"
21
22
"github.com/pion/turn/v2"
22
23
"github.com/spf13/cobra"
24
+ "golang.org/x/oauth2"
25
+ xgithub "golang.org/x/oauth2/github"
23
26
"golang.org/x/xerrors"
24
27
"google.golang.org/api/idtoken"
25
28
"google.golang.org/api/option"
@@ -51,19 +54,23 @@ func server() *cobra.Command {
51
54
dev bool
52
55
postgresURL string
53
56
// provisionerDaemonCount is a uint8 to ensure a number > 0.
54
- provisionerDaemonCount uint8
55
- tlsCertFile string
56
- tlsClientCAFile string
57
- tlsClientAuth string
58
- tlsEnable bool
59
- tlsKeyFile string
60
- tlsMinVersion string
61
- turnRelayAddress string
62
- skipTunnel bool
63
- traceDatadog bool
64
- secureAuthCookie bool
65
- sshKeygenAlgorithmRaw string
66
- spooky bool
57
+ provisionerDaemonCount uint8
58
+ oauth2GithubClientID string
59
+ oauth2GithubClientSecret string
60
+ oauth2GithubAllowedOrganizations []string
61
+ oauth2GithubAllowSignups bool
62
+ tlsCertFile string
63
+ tlsClientCAFile string
64
+ tlsClientAuth string
65
+ tlsEnable bool
66
+ tlsKeyFile string
67
+ tlsMinVersion string
68
+ turnRelayAddress string
69
+ skipTunnel bool
70
+ traceDatadog bool
71
+ secureAuthCookie bool
72
+ sshKeygenAlgorithmRaw string
73
+ spooky bool
67
74
)
68
75
69
76
root := & cobra.Command {
@@ -180,6 +187,13 @@ func server() *cobra.Command {
180
187
TURNServer : turnServer ,
181
188
}
182
189
190
+ if oauth2GithubClientSecret != "" {
191
+ options .GithubOAuth2Config , err = configureGithubOAuth2 (accessURLParsed , oauth2GithubClientID , oauth2GithubClientSecret , oauth2GithubAllowSignups , oauth2GithubAllowedOrganizations )
192
+ if err != nil {
193
+ return xerrors .Errorf ("configure github oauth2: %w" , err )
194
+ }
195
+ }
196
+
183
197
_ , _ = fmt .Fprintf (cmd .ErrOrStderr (), "access-url: %s\n " , accessURL )
184
198
_ , _ = fmt .Fprintf (cmd .ErrOrStderr (), "provisioner-daemons: %d\n " , provisionerDaemonCount )
185
199
_ , _ = fmt .Fprintln (cmd .ErrOrStderr ())
@@ -373,6 +387,14 @@ func server() *cobra.Command {
373
387
cliflag .BoolVarP (root .Flags (), & dev , "dev" , "" , "CODER_DEV_MODE" , false , "Serve Coder in dev mode for tinkering" )
374
388
cliflag .StringVarP (root .Flags (), & postgresURL , "postgres-url" , "" , "CODER_PG_CONNECTION_URL" , "" , "URL of a PostgreSQL database to connect to" )
375
389
cliflag .Uint8VarP (root .Flags (), & provisionerDaemonCount , "provisioner-daemons" , "" , "CODER_PROVISIONER_DAEMONS" , 1 , "The amount of provisioner daemons to create on start." )
390
+ cliflag .StringVarP (root .Flags (), & oauth2GithubClientID , "oauth2-github-client-id" , "" , "CODER_OAUTH2_GITHUB_CLIENT_ID" , "" ,
391
+ "Specifies a client ID to use for oauth2 with GitHub." )
392
+ cliflag .StringVarP (root .Flags (), & oauth2GithubClientSecret , "oauth2-github-client-secret" , "" , "CODER_OAUTH2_GITHUB_CLIENT_SECRET" , "" ,
393
+ "Specifies a client secret to use for oauth2 with GitHub." )
394
+ cliflag .StringArrayVarP (root .Flags (), & oauth2GithubAllowedOrganizations , "oauth2-github-allowed-orgs" , "" , "CODER_OAUTH2_GITHUB_ALLOWED_ORGS" , nil ,
395
+ "Specifies organizations the user must be a member of to authenticate with GitHub." )
396
+ cliflag .BoolVarP (root .Flags (), & oauth2GithubAllowSignups , "oauth2-github-allow-signups" , "" , "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS" , false ,
397
+ "Specifies whether new users can sign up with GitHub." )
376
398
cliflag .BoolVarP (root .Flags (), & tlsEnable , "tls-enable" , "" , "CODER_TLS_ENABLE" , false , "Specifies if TLS will be enabled" )
377
399
cliflag .StringVarP (root .Flags (), & tlsCertFile , "tls-cert-file" , "" , "CODER_TLS_CERT_FILE" , "" ,
378
400
"Specifies the path to the certificate for TLS. It requires a PEM-encoded file. " +
@@ -572,6 +594,42 @@ func configureTLS(listener net.Listener, tlsMinVersion, tlsClientAuth, tlsCertFi
572
594
return tls .NewListener (listener , tlsConfig ), nil
573
595
}
574
596
597
+ func configureGithubOAuth2 (accessURL * url.URL , clientID , clientSecret string , allowSignups bool , allowOrgs []string ) (* coderd.GithubOAuth2Config , error ) {
598
+ redirectURL , err := accessURL .Parse ("/api/v2/users/oauth2/github/callback" )
599
+ if err != nil {
600
+ return nil , xerrors .Errorf ("parse github oauth callback url: %w" , err )
601
+ }
602
+ return & coderd.GithubOAuth2Config {
603
+ OAuth2Config : & oauth2.Config {
604
+ ClientID : clientID ,
605
+ ClientSecret : clientSecret ,
606
+ Endpoint : xgithub .Endpoint ,
607
+ RedirectURL : redirectURL .String (),
608
+ Scopes : []string {
609
+ "read:user" ,
610
+ "read:org" ,
611
+ "user:email" ,
612
+ },
613
+ },
614
+ AllowSignups : allowSignups ,
615
+ AllowOrganizations : allowOrgs ,
616
+ AuthenticatedUser : func (ctx context.Context , client * http.Client ) (* github.User , error ) {
617
+ user , _ , err := github .NewClient (client ).Users .Get (ctx , "" )
618
+ return user , err
619
+ },
620
+ ListEmails : func (ctx context.Context , client * http.Client ) ([]* github.UserEmail , error ) {
621
+ emails , _ , err := github .NewClient (client ).Users .ListEmails (ctx , & github.ListOptions {})
622
+ return emails , err
623
+ },
624
+ ListOrganizationMemberships : func (ctx context.Context , client * http.Client ) ([]* github.Membership , error ) {
625
+ memberships , _ , err := github .NewClient (client ).Organizations .ListOrgMemberships (ctx , & github.ListOrgMembershipsOptions {
626
+ State : "active" ,
627
+ })
628
+ return memberships , err
629
+ },
630
+ }, nil
631
+ }
632
+
575
633
type datadogLogger struct {
576
634
logger slog.Logger
577
635
}
0 commit comments