feat: Add profile pictures to OAuth users (#3855)

This supports GitHub and OIDC login for profile pictures!
This commit is contained in:
Kyle Carberry
2022-09-04 11:44:27 -05:00
committed by GitHub
parent 67c4605370
commit 05e2806ff3
23 changed files with 139 additions and 33 deletions
+20 -1
View File
@@ -144,6 +144,7 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) {
AllowSignups: api.GithubOAuth2Config.AllowSignups,
Email: verifiedEmail.GetEmail(),
Username: ghUser.GetLogin(),
AvatarURL: ghUser.GetAvatarURL(),
})
var httpErr httpError
if xerrors.As(err, &httpErr) {
@@ -207,6 +208,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
Email string `json:"email"`
Verified bool `json:"email_verified"`
Username string `json:"preferred_username"`
Picture string `json:"picture"`
}
err = idToken.Claims(&claims)
if err != nil {
@@ -256,6 +258,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
AllowSignups: api.OIDCConfig.AllowSignups,
Email: claims.Email,
Username: claims.Username,
AvatarURL: claims.Picture,
})
var httpErr httpError
if xerrors.As(err, &httpErr) {
@@ -292,6 +295,7 @@ type oauthLoginParams struct {
AllowSignups bool
Email string
Username string
AvatarURL string
}
type httpError struct {
@@ -410,6 +414,15 @@ func (api *API) oauthLogin(r *http.Request, params oauthLoginParams) (*http.Cook
}
}
needsUpdate := false
if user.AvatarURL.String != params.AvatarURL {
user.AvatarURL = sql.NullString{
String: params.AvatarURL,
Valid: true,
}
needsUpdate = true
}
// If the upstream email or username has changed we should mirror
// that in Coder. Many enterprises use a user's email/username as
// security auditing fields so they need to stay synced.
@@ -417,6 +430,11 @@ func (api *API) oauthLogin(r *http.Request, params oauthLoginParams) (*http.Cook
// provisioning consequences (updates to usernames may delete persistent
// resources such as user home volumes).
if user.Email != params.Email {
user.Email = params.Email
needsUpdate = true
}
if needsUpdate {
// TODO(JonA): Since we're processing updates to a user's upstream
// email/username, it's possible for a different built-in user to
// have already claimed the username.
@@ -425,9 +443,10 @@ func (api *API) oauthLogin(r *http.Request, params oauthLoginParams) (*http.Cook
// user and changes their username.
user, err = tx.UpdateUserProfile(ctx, database.UpdateUserProfileParams{
ID: user.ID,
Email: params.Email,
Email: user.Email,
Username: user.Username,
UpdatedAt: database.Now(),
AvatarURL: user.AvatarURL,
})
if err != nil {
return xerrors.Errorf("update user profile: %w", err)