From 6ba0c371c21237376c292ee92ec067b4a1ef1218 Mon Sep 17 00:00:00 2001 From: SimonErm <33630884+SimonErm@users.noreply.github.com> Date: Tue, 16 Apr 2024 07:41:39 +0200 Subject: [PATCH] Allow `preferred_username` as username source for OIDC (#30454) This PR adds the preferred_username claim as a possible username source for the oauth2_client. Closes #21518 --- custom/conf/app.example.ini | 3 ++- docs/content/administration/config-cheat-sheet.en-us.md | 5 +++-- modules/setting/oauth2.go | 4 +++- routers/web/auth/auth.go | 7 +++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 918252044b..32b51fd7c6 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1553,8 +1553,9 @@ LEVEL = Info ;; The source of the username for new oauth2 accounts: ;; userid = use the userid / sub attribute ;; nickname = use the nickname attribute +;; preferred_username = use the preferred_username attribute ;; email = use the username part of the email attribute -;; Note: `nickname` and `email` options will normalize input strings using the following criteria: +;; Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria: ;; - diacritics are removed ;; - the characters in the set `['´\x60]` are removed ;; - the characters in the set `[\s~+]` are replaced with `-` diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 9de7511964..ff8bcb066c 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -608,9 +608,10 @@ And the following unique queues: - `ENABLE_AUTO_REGISTRATION`: **false**: Automatically create user accounts for new oauth2 users. - `USERNAME`: **nickname**: The source of the username for new oauth2 accounts: - `userid` - use the userid / sub attribute - - `nickname` - use the nickname attribute + - `nickname` - use the nickname + - `preferred_username` - use the preferred_username - `email` - use the username part of the email attribute - - Note: `nickname` and `email` options will normalize input strings using the following criteria: + - Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria: - diacritics are removed - the characters in the set `['´\x60]` are removed - the characters in the set `[\s~+]` are replaced with `-` diff --git a/modules/setting/oauth2.go b/modules/setting/oauth2.go index 830472db32..6930197b22 100644 --- a/modules/setting/oauth2.go +++ b/modules/setting/oauth2.go @@ -22,11 +22,13 @@ const ( OAuth2UsernameNickname OAuth2UsernameType = "nickname" // OAuth2UsernameEmail username of oauth2 email field will be used as gitea name OAuth2UsernameEmail OAuth2UsernameType = "email" + // OAuth2UsernameEmail username of oauth2 preferred_username field will be used as gitea name + OAuth2UsernamePreferredUsername OAuth2UsernameType = "preferred_username" ) func (username OAuth2UsernameType) isValid() bool { switch username { - case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail: + case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail, OAuth2UsernamePreferredUsername: return true } return false diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 8b5cd986b8..9ef32ebdb1 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -386,6 +386,13 @@ func getUserName(gothUser *goth.User) (string, error) { switch setting.OAuth2Client.Username { case setting.OAuth2UsernameEmail: return user_model.NormalizeUserName(strings.Split(gothUser.Email, "@")[0]) + case setting.OAuth2UsernamePreferredUsername: + preferredUsername, exists := gothUser.RawData["preferred_username"] + if exists { + return user_model.NormalizeUserName(preferredUsername.(string)) + } else { + return "", fmt.Errorf("preferred_username is missing in received user data but configured as username source for user_id %q. Check if OPENID_CONNECT_SCOPES contains profile", gothUser.UserID) + } case setting.OAuth2UsernameNickname: return user_model.NormalizeUserName(gothUser.NickName) default: // OAuth2UsernameUserid