fix(auth): support employee ID usernames
giteabot backport / giteabot (push) Canceled after 0s
giteabot / giteabot (push) Canceled after 0s
release-nightly / nightly-binary (push) Canceled after 0s
release-nightly / nightly-container (push) Canceled after 0s
release-nightly-snapcraft / build-and-publish (push) Canceled after 0s
giteabot backport / giteabot (push) Canceled after 0s
giteabot / giteabot (push) Canceled after 0s
release-nightly / nightly-binary (push) Canceled after 0s
release-nightly / nightly-container (push) Canceled after 0s
release-nightly-snapcraft / build-and-publish (push) Canceled after 0s
Assisted-by: Codex:GPT-5
This commit is contained in:
@@ -1735,8 +1735,9 @@ LEVEL = Info
|
|||||||
;; userid = use the userid / sub attribute
|
;; userid = use the userid / sub attribute
|
||||||
;; nickname = use the nickname attribute
|
;; nickname = use the nickname attribute
|
||||||
;; preferred_username = use the preferred_username attribute
|
;; preferred_username = use the preferred_username attribute
|
||||||
|
;; employee_id = use the employee_id attribute (requires the provider to return this custom claim)
|
||||||
;; email = use the username part of the email attribute
|
;; email = use the username part of the email attribute
|
||||||
;; Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria:
|
;; Note: `nickname`, `preferred_username`, `employee_id` and `email` options will normalize input strings using the following criteria:
|
||||||
;; - diacritics are removed
|
;; - diacritics are removed
|
||||||
;; - the characters in the set ['´`] are removed
|
;; - the characters in the set ['´`] are removed
|
||||||
;; - the characters in the set [\s~+] are replaced with "-"
|
;; - the characters in the set [\s~+] are replaced with "-"
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ const (
|
|||||||
OAuth2UsernameNickname OAuth2UsernameType = "nickname" // use nickname field
|
OAuth2UsernameNickname OAuth2UsernameType = "nickname" // use nickname field
|
||||||
OAuth2UsernameEmail OAuth2UsernameType = "email" // use email field
|
OAuth2UsernameEmail OAuth2UsernameType = "email" // use email field
|
||||||
OAuth2UsernamePreferredUsername OAuth2UsernameType = "preferred_username" // use preferred_username field
|
OAuth2UsernamePreferredUsername OAuth2UsernameType = "preferred_username" // use preferred_username field
|
||||||
|
OAuth2UsernameEmployeeID OAuth2UsernameType = "employee_id" // use employee_id field
|
||||||
)
|
)
|
||||||
|
|
||||||
func (username OAuth2UsernameType) isValid() bool {
|
func (username OAuth2UsernameType) isValid() bool {
|
||||||
switch username {
|
switch username {
|
||||||
case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail, OAuth2UsernamePreferredUsername:
|
case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail, OAuth2UsernamePreferredUsername, OAuth2UsernameEmployeeID:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -88,3 +88,11 @@ ENABLE_OPENID_CONNECT_PKCE = true
|
|||||||
loadOAuth2ClientFrom(cfg)
|
loadOAuth2ClientFrom(cfg)
|
||||||
assert.True(t, OAuth2Client.EnableOpenIDConnectPKCE)
|
assert.True(t, OAuth2Client.EnableOpenIDConnectPKCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOAuth2ClientEmployeeIDUsername(t *testing.T) {
|
||||||
|
cfg, _ := NewConfigProviderFromData(`[oauth2_client]
|
||||||
|
USERNAME = employee_id
|
||||||
|
`)
|
||||||
|
loadOAuth2ClientFrom(cfg)
|
||||||
|
assert.Equal(t, OAuth2UsernameEmployeeID, OAuth2Client.Username)
|
||||||
|
}
|
||||||
|
|||||||
@@ -450,6 +450,11 @@ func extractUserNameFromOAuth2(gothUser *goth.User) (string, error) {
|
|||||||
return user_model.NormalizeUserName(preferredUsername)
|
return user_model.NormalizeUserName(preferredUsername)
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
|
case setting.OAuth2UsernameEmployeeID:
|
||||||
|
if employeeID, ok := gothUser.RawData["employee_id"].(string); ok {
|
||||||
|
return user_model.NormalizeUserName(employeeID)
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
case setting.OAuth2UsernameNickname:
|
case setting.OAuth2UsernameNickname:
|
||||||
return user_model.NormalizeUserName(gothUser.NickName)
|
return user_model.NormalizeUserName(gothUser.NickName)
|
||||||
default: // OAuth2UsernameUserid
|
default: // OAuth2UsernameUserid
|
||||||
|
|||||||
@@ -184,6 +184,20 @@ func TestWebAuthOAuth2(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExtractUserNameFromOAuth2EmployeeID(t *testing.T) {
|
||||||
|
defer test.MockVariableValue(&setting.OAuth2Client.Username, setting.OAuth2UsernameEmployeeID)()
|
||||||
|
|
||||||
|
username, err := extractUserNameFromOAuth2(&goth.User{
|
||||||
|
RawData: map[string]any{"employee_id": "RC001"},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "RC001", username)
|
||||||
|
|
||||||
|
username, err = extractUserNameFromOAuth2(&goth.User{RawData: map[string]any{}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Empty(t, username)
|
||||||
|
}
|
||||||
|
|
||||||
func TestOpenIDRequireTwoFactor(t *testing.T) {
|
func TestOpenIDRequireTwoFactor(t *testing.T) {
|
||||||
require.NoError(t, unittest.PrepareTestDatabase())
|
require.NoError(t, unittest.PrepareTestDatabase())
|
||||||
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockMemStore("dummy-sid-openid")}
|
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockMemStore("dummy-sid-openid")}
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ func SignInOAuthCallback(ctx *context.Context) {
|
|||||||
missingFields = append(missingFields, "nickname")
|
missingFields = append(missingFields, "nickname")
|
||||||
case setting.OAuth2UsernamePreferredUsername:
|
case setting.OAuth2UsernamePreferredUsername:
|
||||||
missingFields = append(missingFields, "preferred_username")
|
missingFields = append(missingFields, "preferred_username")
|
||||||
|
case setting.OAuth2UsernameEmployeeID:
|
||||||
|
missingFields = append(missingFields, "employee_id")
|
||||||
} // else: "UserID" and "Email" have been handled above separately
|
} // else: "UserID" and "Email" have been handled above separately
|
||||||
}
|
}
|
||||||
if len(missingFields) > 0 {
|
if len(missingFields) > 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user