@@ -14,6 +14,7 @@ import (
14
14
"github.com/golang-jwt/jwt/v4"
15
15
"github.com/google/go-github/v43/github"
16
16
"github.com/google/uuid"
17
+ "github.com/prometheus/client_golang/prometheus"
17
18
"github.com/stretchr/testify/require"
18
19
"golang.org/x/xerrors"
19
20
@@ -25,6 +26,7 @@ import (
25
26
"github.com/coder/coder/v2/coderd/database"
26
27
"github.com/coder/coder/v2/coderd/database/dbgen"
27
28
"github.com/coder/coder/v2/coderd/database/dbtestutil"
29
+ "github.com/coder/coder/v2/coderd/promoauth"
28
30
"github.com/coder/coder/v2/codersdk"
29
31
"github.com/coder/coder/v2/testutil"
30
32
)
@@ -205,6 +207,7 @@ func TestUserOAuth2Github(t *testing.T) {
205
207
},
206
208
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
207
209
return & github.User {
210
+ ID :github .Int64 (100 ),
208
211
Login :github .String ("kyle" ),
209
212
},nil
210
213
},
@@ -264,7 +267,9 @@ func TestUserOAuth2Github(t *testing.T) {
264
267
}},nil
265
268
},
266
269
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
267
- return & github.User {},nil
270
+ return & github.User {
271
+ ID :github .Int64 (100 ),
272
+ },nil
268
273
},
269
274
ListEmails :func (ctx context.Context ,client * http.Client ) ([]* github.UserEmail ,error ) {
270
275
return []* github.UserEmail {{
@@ -295,7 +300,9 @@ func TestUserOAuth2Github(t *testing.T) {
295
300
}},nil
296
301
},
297
302
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
298
- return & github.User {},nil
303
+ return & github.User {
304
+ ID :github .Int64 (100 ),
305
+ },nil
299
306
},
300
307
ListEmails :func (ctx context.Context ,client * http.Client ) ([]* github.UserEmail ,error ) {
301
308
return []* github.UserEmail {{
@@ -390,6 +397,7 @@ func TestUserOAuth2Github(t *testing.T) {
390
397
},
391
398
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
392
399
return & github.User {
400
+ ID :github .Int64 (100 ),
393
401
Login :github .String ("kyle" ),
394
402
},nil
395
403
},
@@ -442,6 +450,7 @@ func TestUserOAuth2Github(t *testing.T) {
442
450
},
443
451
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
444
452
return & github.User {
453
+ ID :github .Int64 (100 ),
445
454
Login :github .String ("mathias" ),
446
455
},nil
447
456
},
@@ -494,6 +503,7 @@ func TestUserOAuth2Github(t *testing.T) {
494
503
},
495
504
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
496
505
return & github.User {
506
+ ID :github .Int64 (100 ),
497
507
Login :github .String ("mathias" ),
498
508
},nil
499
509
},
@@ -532,6 +542,7 @@ func TestUserOAuth2Github(t *testing.T) {
532
542
},
533
543
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
534
544
return & github.User {
545
+ ID :github .Int64 (100 ),
535
546
Login :github .String ("mathias" ),
536
547
},nil
537
548
},
@@ -574,6 +585,7 @@ func TestUserOAuth2Github(t *testing.T) {
574
585
},
575
586
AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
576
587
return & github.User {
588
+ ID :github .Int64 (100 ),
577
589
Login :github .String ("kyle" ),
578
590
},nil
579
591
},
@@ -591,6 +603,87 @@ func TestUserOAuth2Github(t *testing.T) {
591
603
592
604
require .Equal (t ,http .StatusUnauthorized ,resp .StatusCode )
593
605
})
606
+ t .Run ("ChangedEmail" ,func (t * testing.T ) {
607
+ t .Parallel ()
608
+
609
+ fake := oidctest .NewFakeIDP (t ,
610
+ oidctest .WithServing (),
611
+ oidctest .WithCallbackPath ("/api/v2/users/oauth2/github/callback" ),
612
+ )
613
+ const ghID = int64 (7777 )
614
+ auditor := audit .NewMock ()
615
+ coderEmail := & github.UserEmail {
616
+ Email :github .String ("alice@coder.com" ),
617
+ Verified :github .Bool (true ),
618
+ Primary :github .Bool (true ),
619
+ }
620
+ gmailEmail := & github.UserEmail {
621
+ Email :github .String ("alice@gmail.com" ),
622
+ Verified :github .Bool (true ),
623
+ Primary :github .Bool (false ),
624
+ }
625
+ emails := []* github.UserEmail {
626
+ gmailEmail ,
627
+ coderEmail ,
628
+ }
629
+
630
+ client := coderdtest .New (t ,& coderdtest.Options {
631
+ Auditor :auditor ,
632
+ GithubOAuth2Config :& coderd.GithubOAuth2Config {
633
+ AllowSignups :true ,
634
+ AllowEveryone :true ,
635
+ OAuth2Config :promoauth .NewFactory (prometheus .NewRegistry ()).NewGithub ("test-github" ,fake .OIDCConfig (t , []string {})),
636
+ ListOrganizationMemberships :func (ctx context.Context ,client * http.Client ) ([]* github.Membership ,error ) {
637
+ return []* github.Membership {},nil
638
+ },
639
+ TeamMembership :func (ctx context.Context ,client * http.Client ,org ,team ,username string ) (* github.Membership ,error ) {
640
+ return nil ,xerrors .New ("no teams" )
641
+ },
642
+ AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
643
+ return & github.User {
644
+ Login :github .String ("alice" ),
645
+ ID :github .Int64 (ghID ),
646
+ },nil
647
+ },
648
+ ListEmails :func (ctx context.Context ,client * http.Client ) ([]* github.UserEmail ,error ) {
649
+ return emails ,nil
650
+ },
651
+ },
652
+ })
653
+
654
+ ctx := testutil .Context (t ,testutil .WaitMedium )
655
+ // This should register the user
656
+ client ,_ = fake .Login (t ,client , jwt.MapClaims {})
657
+ user ,err := client .User (ctx ,"me" )
658
+ require .NoError (t ,err )
659
+ userID := user .ID
660
+ require .Equal (t ,user .Email ,* coderEmail .Email )
661
+
662
+ // Now the user is registered, let's change their primary email.
663
+ coderEmail .Primary = github .Bool (false )
664
+ gmailEmail .Primary = github .Bool (true )
665
+
666
+ client ,_ = fake .Login (t ,client , jwt.MapClaims {})
667
+ user ,err = client .User (ctx ,"me" )
668
+ require .NoError (t ,err )
669
+ require .Equal (t ,user .ID ,userID )
670
+ require .Equal (t ,user .Email ,* gmailEmail .Email )
671
+
672
+ // Entirely change emails.
673
+ newEmail := "alice@newdomain.com"
674
+ emails = []* github.UserEmail {
675
+ {
676
+ Email :github .String ("alice@newdomain.com" ),
677
+ Primary :github .Bool (true ),
678
+ Verified :github .Bool (true ),
679
+ },
680
+ }
681
+ client ,_ = fake .Login (t ,client , jwt.MapClaims {})
682
+ user ,err = client .User (ctx ,"me" )
683
+ require .NoError (t ,err )
684
+ require .Equal (t ,user .ID ,userID )
685
+ require .Equal (t ,user .Email ,newEmail )
686
+ })
594
687
}
595
688
596
689
// nolint:bodyclose