@@ -30,6 +30,10 @@ import (
30
30
"github.com/coder/coder/codersdk"
31
31
)
32
32
33
+ const (
34
+ userAuthLoggerName = "userauth"
35
+ )
36
+
33
37
// Authenticates the user with an email and password.
34
38
//
35
39
// @Summary Log in user
@@ -59,11 +63,14 @@ func (api *API) postLogin(rw http.ResponseWriter, r *http.Request) {
59
63
return
60
64
}
61
65
66
+ logger := api .Logger .Named (userAuthLoggerName )
67
+
62
68
//nolint:gocritic // In order to login, we need to get the user first!
63
69
user , err := api .Database .GetUserByEmailOrUsername (dbauthz .AsSystemRestricted (ctx ), database.GetUserByEmailOrUsernameParams {
64
70
Email : loginWithPassword .Email ,
65
71
})
66
72
if err != nil && ! xerrors .Is (err , sql .ErrNoRows ) {
73
+ logger .Error (ctx , "unable to fetch user by email" , slog .Error (err ))
67
74
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
68
75
Message : "Internal error." ,
69
76
})
@@ -75,6 +82,7 @@ func (api *API) postLogin(rw http.ResponseWriter, r *http.Request) {
75
82
// If the user doesn't exist, it will be a default struct.
76
83
equal , err := userpassword .Compare (string (user .HashedPassword ), loginWithPassword .Password )
77
84
if err != nil {
85
+ logger .Error (ctx , "unable to compare passwords" , slog .Error (err ))
78
86
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
79
87
Message : "Internal error." ,
80
88
})
@@ -108,6 +116,7 @@ func (api *API) postLogin(rw http.ResponseWriter, r *http.Request) {
108
116
//nolint:gocritic // System needs to fetch user roles in order to login user.
109
117
roles , err := api .Database .GetAuthorizationUserRoles (dbauthz .AsSystemRestricted (ctx ), user .ID )
110
118
if err != nil {
119
+ logger .Error (ctx , "unable to fetch authorization user roles" , slog .Error (err ))
111
120
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
112
121
Message : "Internal error." ,
113
122
})
@@ -137,6 +146,7 @@ func (api *API) postLogin(rw http.ResponseWriter, r *http.Request) {
137
146
DeploymentValues : api .DeploymentValues ,
138
147
})
139
148
if err != nil {
149
+ logger .Error (ctx , "unable to create API key" , slog .Error (err ))
140
150
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
141
151
Message : "Failed to create API key." ,
142
152
Detail : err .Error (),
@@ -188,8 +198,11 @@ func (api *API) postLogout(rw http.ResponseWriter, r *http.Request) {
188
198
apiKey := httpmw .APIKey (r )
189
199
aReq .Old = apiKey
190
200
201
+ logger := api .Logger .Named (userAuthLoggerName )
202
+
191
203
err := api .Database .DeleteAPIKeyByID (ctx , apiKey .ID )
192
204
if err != nil {
205
+ logger .Error (ctx , "unable to delete API key" , slog .F ("api_key" , apiKey .ID ), slog .Error (err ))
193
206
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
194
207
Message : "Internal error deleting API key." ,
195
208
Detail : err .Error (),
@@ -203,6 +216,7 @@ func (api *API) postLogout(rw http.ResponseWriter, r *http.Request) {
203
216
// to access the app again.
204
217
err = api .Database .DeleteApplicationConnectAPIKeysByUserID (ctx , apiKey .UserID )
205
218
if err != nil {
219
+ logger .Error (ctx , "unable to invalidate subdomain app tokens" , slog .F ("user_id" , apiKey .UserID ), slog .Error (err ))
206
220
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
207
221
Message : "Internal error deleting app tokens." ,
208
222
Detail : err .Error (),
@@ -293,11 +307,14 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
293
307
294
308
oauthClient := oauth2 .NewClient (ctx , oauth2 .StaticTokenSource (state .Token ))
295
309
310
+ logger := api .Logger .Named (userAuthLoggerName )
311
+
296
312
var selectedMemberships []* github.Membership
297
313
var organizationNames []string
298
314
if ! api .GithubOAuth2Config .AllowEveryone {
299
315
memberships , err := api .GithubOAuth2Config .ListOrganizationMemberships (ctx , oauthClient )
300
316
if err != nil {
317
+ logger .Error (ctx , "unable to list organization members" , slog .Error (err ))
301
318
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
302
319
Message : "Internal error fetching authenticated Github user organizations." ,
303
320
Detail : err .Error (),
@@ -328,6 +345,7 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
328
345
329
346
ghUser , err := api .GithubOAuth2Config .AuthenticatedUser (ctx , oauthClient )
330
347
if err != nil {
348
+ logger .Error (ctx , "oauth2: unable to fetch authenticated user" , slog .Error (err ))
331
349
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
332
350
Message : "Internal error fetching authenticated Github user." ,
333
351
Detail : err .Error (),
@@ -366,6 +384,7 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
366
384
367
385
emails , err := api .GithubOAuth2Config .ListEmails (ctx , oauthClient )
368
386
if err != nil {
387
+ logger .Error (ctx , "oauth2: unable to list emails" , slog .Error (err ))
369
388
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
370
389
Message : "Internal error fetching personal Github user." ,
371
390
Detail : err .Error (),
@@ -390,6 +409,7 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
390
409
391
410
user , link , err := findLinkedUser (ctx , api .Database , githubLinkedID (ghUser ), verifiedEmail .GetEmail ())
392
411
if err != nil {
412
+ logger .Error (ctx , "oauth2: unable to find linked user" , slog .F ("gh_user" , ghUser .Name ), slog .Error (err ))
393
413
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
394
414
Message : "Failed to find linked user." ,
395
415
Detail : err .Error (),
@@ -423,6 +443,7 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
423
443
return
424
444
}
425
445
if err != nil {
446
+ logger .Error (ctx , "oauth2: login failed" , slog .F ("user" , user .Username ), slog .Error (err ))
426
447
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
427
448
Message : "Failed to process OAuth login." ,
428
449
Detail : err .Error (),
@@ -521,20 +542,23 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
521
542
return
522
543
}
523
544
545
+ logger := api .Logger .Named (userAuthLoggerName )
546
+
524
547
// "email_verified" is an optional claim that changes the behavior
525
548
// of our OIDC handler, so each property must be pulled manually out
526
549
// of the claim mapping.
527
550
claims := map [string ]interface {}{}
528
551
err = idToken .Claims (& claims )
529
552
if err != nil {
553
+ logger .Error (ctx , "oauth2: unable to extract OIDC claims" , slog .Error (err ))
530
554
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
531
555
Message : "Failed to extract OIDC claims." ,
532
556
Detail : err .Error (),
533
557
})
534
558
return
535
559
}
536
560
537
- api . Logger .Debug (ctx , "got oidc claims" ,
561
+ logger .Debug (ctx , "got oidc claims" ,
538
562
slog .F ("source" , "id_token" ),
539
563
slog .F ("claim_fields" , claimFields (claims )),
540
564
slog .F ("blank" , blankFields (claims )),
@@ -556,13 +580,14 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
556
580
userInfoClaims := map [string ]interface {}{}
557
581
err = userInfo .Claims (& userInfoClaims )
558
582
if err != nil {
583
+ logger .Error (ctx , "oauth2: unable to unmarshal user info claims" , slog .Error (err ))
559
584
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
560
585
Message : "Failed to unmarshal user info claims." ,
561
586
Detail : err .Error (),
562
587
})
563
588
return
564
589
}
565
- api . Logger .Debug (ctx , "got oidc claims" ,
590
+ logger .Debug (ctx , "got oidc claims" ,
566
591
slog .F ("source" , "userinfo" ),
567
592
slog .F ("claim_fields" , claimFields (userInfoClaims )),
568
593
slog .F ("blank" , blankFields (userInfoClaims )),
@@ -573,12 +598,13 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
573
598
claims = mergeClaims (claims , userInfoClaims )
574
599
575
600
// Log all of the field names after merging.
576
- api . Logger .Debug (ctx , "got oidc claims" ,
601
+ logger .Debug (ctx , "got oidc claims" ,
577
602
slog .F ("source" , "merged" ),
578
603
slog .F ("claim_fields" , claimFields (claims )),
579
604
slog .F ("blank" , blankFields (claims )),
580
605
)
581
606
} else if ! strings .Contains (err .Error (), "user info endpoint is not supported by this provider" ) {
607
+ logger .Error (ctx , "oauth2: unable to obtain user information claims" , slog .Error (err ))
582
608
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
583
609
Message : "Failed to obtain user information claims." ,
584
610
Detail : "The attempt to fetch claims via the UserInfo endpoint failed: " + err .Error (),
@@ -588,7 +614,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
588
614
// The OIDC provider does not support the UserInfo endpoint.
589
615
// This is not an error, but we should log it as it may mean
590
616
// that some claims are missing.
591
- api . Logger .Warn (ctx , "OIDC provider does not support the user info endpoint, ensure that all required claims are present in the id_token" )
617
+ logger .Warn (ctx , "OIDC provider does not support the user info endpoint, ensure that all required claims are present in the id_token" )
592
618
}
593
619
}
594
620
@@ -632,7 +658,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
632
658
})
633
659
return
634
660
}
635
- api . Logger .Warn (ctx , "allowing unverified oidc email %q" )
661
+ logger .Warn (ctx , "allowing unverified oidc email %q" )
636
662
}
637
663
}
638
664
@@ -647,7 +673,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
647
673
// Convert the []interface{} we get to a []string.
648
674
groupsInterface , ok := groupsRaw .([]interface {})
649
675
if ok {
650
- api . Logger .Debug (ctx , "groups returned in oidc claims" ,
676
+ logger .Debug (ctx , "groups returned in oidc claims" ,
651
677
slog .F ("len" , len (groupsInterface )),
652
678
slog .F ("groups" , groupsInterface ),
653
679
)
@@ -668,7 +694,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
668
694
groups = append (groups , group )
669
695
}
670
696
} else {
671
- api . Logger .Debug (ctx , "groups field was an unknown type" ,
697
+ logger .Debug (ctx , "groups field was an unknown type" ,
672
698
slog .F ("type" , fmt .Sprintf ("%T" , groupsRaw )),
673
699
)
674
700
}
@@ -678,7 +704,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
678
704
// This conditional is purely to warn the user they might have misconfigured their OIDC
679
705
// configuration.
680
706
if _ , groupClaimExists := claims ["groups" ]; ! usingGroups && groupClaimExists {
681
- api . Logger .Debug (ctx , "claim 'groups' was returned, but 'oidc-group-field' is not set, check your coder oidc settings" )
707
+ logger .Debug (ctx , "claim 'groups' was returned, but 'oidc-group-field' is not set, check your coder oidc settings" )
682
708
}
683
709
684
710
// The username is a required property in Coder. We make a best-effort
@@ -719,6 +745,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
719
745
720
746
user , link , err := findLinkedUser (ctx , api .Database , oidcLinkedID (idToken ), email )
721
747
if err != nil {
748
+ logger .Error (ctx , "oauth2: unable to find linked user" , slog .F ("email" , email ), slog .Error (err ))
722
749
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
723
750
Message : "Failed to find linked user." ,
724
751
Detail : err .Error (),
@@ -754,6 +781,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
754
781
return
755
782
}
756
783
if err != nil {
784
+ logger .Error (ctx , "oauth2: login failed" , slog .F ("user" , user .Username ), slog .Error (err ))
757
785
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
758
786
Message : "Failed to process OAuth login." ,
759
787
Detail : err .Error (),
0 commit comments