@@ -45,6 +45,8 @@ import (
4545"github.com/coder/coder/v2/cli/clitest"
4646"github.com/coder/coder/v2/cli/config"
4747"github.com/coder/coder/v2/coderd/coderdtest"
48+ "github.com/coder/coder/v2/coderd/database"
49+ "github.com/coder/coder/v2/coderd/database/dbgen"
4850"github.com/coder/coder/v2/coderd/database/dbtestutil"
4951"github.com/coder/coder/v2/coderd/database/migrations"
5052"github.com/coder/coder/v2/coderd/httpapi"
@@ -306,6 +308,145 @@ func TestServer(t *testing.T) {
306308require .Less (t ,numLines ,20 )
307309})
308310
311+ t .Run ("OAuth2GitHubDefaultProvider" ,func (t * testing.T ) {
312+ type testCase struct {
313+ name string
314+ githubDefaultProviderEnabled string
315+ githubClientID string
316+ githubClientSecret string
317+ expectGithubEnabled bool
318+ expectGithubDefaultProviderConfigured bool
319+ createUserPreStart bool
320+ createUserPostRestart bool
321+ }
322+
323+ runGitHubProviderTest := func (t * testing.T ,tc testCase ) {
324+ t .Parallel ()
325+ if ! dbtestutil .WillUsePostgres () {
326+ t .Skip ("test requires postgres" )
327+ }
328+
329+ ctx ,cancelFunc := context .WithCancel (testutil .Context (t ,testutil .WaitLong ))
330+ defer cancelFunc ()
331+
332+ dbURL ,err := dbtestutil .Open (t )
333+ require .NoError (t ,err )
334+ db ,_ := dbtestutil .NewDB (t ,dbtestutil .WithURL (dbURL ))
335+
336+ if tc .createUserPreStart {
337+ _ = dbgen .User (t ,db , database.User {})
338+ }
339+
340+ args := []string {
341+ "server" ,
342+ "--postgres-url" ,dbURL ,
343+ "--http-address" ,":0" ,
344+ "--access-url" ,"https://example.com" ,
345+ }
346+ if tc .githubClientID != "" {
347+ args = append (args ,fmt .Sprintf ("--oauth2-github-client-id=%s" ,tc .githubClientID ))
348+ }
349+ if tc .githubClientSecret != "" {
350+ args = append (args ,fmt .Sprintf ("--oauth2-github-client-secret=%s" ,tc .githubClientSecret ))
351+ }
352+ if tc .githubClientID != "" || tc .githubClientSecret != "" {
353+ args = append (args ,"--oauth2-github-allow-everyone" )
354+ }
355+ if tc .githubDefaultProviderEnabled != "" {
356+ args = append (args ,fmt .Sprintf ("--oauth2-github-default-provider-enable=%s" ,tc .githubDefaultProviderEnabled ))
357+ }
358+
359+ inv ,cfg := clitest .New (t ,args ... )
360+ errChan := make (chan error ,1 )
361+ go func () {
362+ errChan <- inv .WithContext (ctx ).Run ()
363+ }()
364+ accessURLChan := make (chan * url.URL ,1 )
365+ go func () {
366+ accessURLChan <- waitAccessURL (t ,cfg )
367+ }()
368+
369+ var accessURL * url.URL
370+ select {
371+ case err := <- errChan :
372+ require .NoError (t ,err )
373+ case accessURL = <- accessURLChan :
374+ require .NotNil (t ,accessURL )
375+ }
376+
377+ client := codersdk .New (accessURL )
378+
379+ authMethods ,err := client .AuthMethods (ctx )
380+ require .NoError (t ,err )
381+ require .Equal (t ,tc .expectGithubEnabled ,authMethods .Github .Enabled )
382+ require .Equal (t ,tc .expectGithubDefaultProviderConfigured ,authMethods .Github .DefaultProviderConfigured )
383+
384+ cancelFunc ()
385+ select {
386+ case err := <- errChan :
387+ require .NoError (t ,err )
388+ case <- time .After (testutil .WaitLong ):
389+ t .Fatal ("server did not exit" )
390+ }
391+
392+ if tc .createUserPostRestart {
393+ _ = dbgen .User (t ,db , database.User {})
394+ }
395+
396+ // Ensure that it stays at that setting after the server restarts.
397+ inv ,cfg = clitest .New (t ,args ... )
398+ clitest .Start (t ,inv )
399+ accessURL = waitAccessURL (t ,cfg )
400+ client = codersdk .New (accessURL )
401+
402+ ctx = testutil .Context (t ,testutil .WaitLong )
403+ authMethods ,err = client .AuthMethods (ctx )
404+ require .NoError (t ,err )
405+ require .Equal (t ,tc .expectGithubEnabled ,authMethods .Github .Enabled )
406+ require .Equal (t ,tc .expectGithubDefaultProviderConfigured ,authMethods .Github .DefaultProviderConfigured )
407+ }
408+
409+ for _ ,tc := range []testCase {
410+ {
411+ name :"NewDeployment" ,
412+ expectGithubEnabled :true ,
413+ expectGithubDefaultProviderConfigured :true ,
414+ createUserPreStart :false ,
415+ createUserPostRestart :true ,
416+ },
417+ {
418+ name :"ExistingDeployment" ,
419+ expectGithubEnabled :false ,
420+ expectGithubDefaultProviderConfigured :false ,
421+ createUserPreStart :true ,
422+ createUserPostRestart :false ,
423+ },
424+ {
425+ name :"ManuallyDisabled" ,
426+ githubDefaultProviderEnabled :"false" ,
427+ expectGithubEnabled :false ,
428+ expectGithubDefaultProviderConfigured :false ,
429+ },
430+ {
431+ name :"ConfiguredClientID" ,
432+ githubClientID :"123" ,
433+ expectGithubEnabled :true ,
434+ expectGithubDefaultProviderConfigured :false ,
435+ },
436+ {
437+ name :"ConfiguredClientSecret" ,
438+ githubClientSecret :"456" ,
439+ expectGithubEnabled :true ,
440+ expectGithubDefaultProviderConfigured :false ,
441+ },
442+ } {
443+ tc := tc
444+ t .Run (tc .name ,func (t * testing.T ) {
445+ runGitHubProviderTest (t ,tc )
446+ })
447+ }
448+ })
449+
309450// Validate that a warning is printed that it may not be externally
310451// reachable.
311452t .Run ("LocalAccessURL" ,func (t * testing.T ) {