fix: make "login_name" field optional for API edit user (#38917) (#38945)

Backport #38917

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Giteabot
2026-08-16 07:03:57 -07:00
committed by GitHub
parent 5a665c0b0e
commit cbcf36cded
6 changed files with 9 additions and 43 deletions
+1 -4
View File
@@ -11,7 +11,6 @@ type CreateUserOption struct {
// The authentication source ID to associate with the user
SourceID int64 `json:"source_id"`
// identifier of the user, provided by the external authenticator (if configured)
// default: empty
LoginName string `json:"login_name"`
// username of the user
// required: true
@@ -44,9 +43,7 @@ type EditUserOption struct {
// The authentication source ID to associate with the user
SourceID int64 `json:"source_id"`
// identifier of the user, provided by the external authenticator (if configured)
// default: empty
// required: true
LoginName string `json:"login_name" binding:"Required"`
LoginName *string `json:"login_name"`
// swagger:strfmt email
// The email address of the user
Email *string `json:"email" binding:"MaxSize(254)"`
-1
View File
@@ -18,7 +18,6 @@ type User struct {
// login of the user, same as `username`
UserName string `json:"login"`
// identifier of the user, provided by the external authenticator (if configured)
// default: empty
LoginName string `json:"login_name"`
// The ID of the user's Authentication Source
SourceID int64 `json:"source_id"`
+1 -1
View File
@@ -194,7 +194,7 @@ func EditUser(ctx *context.APIContext) {
authOpts := &user_service.UpdateAuthOptions{
LoginSource: optional.FromNonDefault(form.SourceID),
LoginName: optional.Some(form.LoginName),
LoginName: optional.FromPtr(form.LoginName),
Password: optional.FromNonDefault(form.Password),
MustChangePassword: optional.FromPtr(form.MustChangePassword),
ProhibitLogin: optional.FromPtr(form.ProhibitLogin),
+1 -5
View File
@@ -25063,7 +25063,6 @@
"login_name": {
"description": "identifier of the user, provided by the external authenticator (if configured)",
"type": "string",
"default": "empty",
"x-go-name": "LoginName"
},
"must_change_password": {
@@ -26249,8 +26248,7 @@
"description": "EditUserOption edit user options",
"type": "object",
"required": [
"source_id",
"login_name"
"source_id"
],
"properties": {
"active": {
@@ -26301,7 +26299,6 @@
"login_name": {
"description": "identifier of the user, provided by the external authenticator (if configured)",
"type": "string",
"default": "empty",
"x-go-name": "LoginName"
},
"max_repo_creation": {
@@ -30658,7 +30655,6 @@
"login_name": {
"description": "identifier of the user, provided by the external authenticator (if configured)",
"type": "string",
"default": "empty",
"x-go-name": "LoginName"
},
"prohibit_login": {
+1 -5
View File
@@ -4835,7 +4835,6 @@
"x-go-name": "FullName"
},
"login_name": {
"default": "empty",
"description": "identifier of the user, provided by the external authenticator (if configured)",
"type": "string",
"x-go-name": "LoginName"
@@ -6058,7 +6057,6 @@
"x-go-name": "Location"
},
"login_name": {
"default": "empty",
"description": "identifier of the user, provided by the external authenticator (if configured)",
"type": "string",
"x-go-name": "LoginName"
@@ -6109,8 +6107,7 @@
}
},
"required": [
"source_id",
"login_name"
"source_id"
],
"type": "object",
"x-go-package": "gitea.dev/modules/structs"
@@ -10469,7 +10466,6 @@
"x-go-name": "UserName"
},
"login_name": {
"default": "empty",
"description": "identifier of the user, provided by the external authenticator (if configured)",
"type": "string",
"x-go-name": "LoginName"
+5 -27
View File
@@ -204,12 +204,7 @@ func TestAPIEditUser(t *testing.T) {
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"})
assert.Equal(t, fullNameToChange, user2.FullName)
empty := ""
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
LoginName: "user2",
SourceID: 0,
Email: &empty,
}).AddTokenAuth(token)
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{SourceID: 0, Email: new("")}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusBadRequest)
errMap := make(map[string]any)
@@ -218,14 +213,7 @@ func TestAPIEditUser(t *testing.T) {
user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"})
assert.False(t, user2.IsRestricted)
bTrue := true
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
// required
LoginName: "user2",
SourceID: 0,
// to change
Restricted: &bTrue,
}).AddTokenAuth(token)
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{Restricted: new(true)}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)
user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"})
assert.True(t, user2.IsRestricted)
@@ -361,24 +349,14 @@ func TestAPIEditUser_NotAllowedEmailDomain(t *testing.T) {
adminUsername := "user1"
token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin)
urlStr := "/api/v1/admin/users/" + "user2"
urlStr := "/api/v1/admin/users/user2"
newEmail := "user2@example1.com"
req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
LoginName: "user2",
SourceID: 0,
Email: &newEmail,
}).AddTokenAuth(token)
req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{Email: new("user2@example1.com")}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusBadRequest)
errMap := make(map[string]string)
assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), &errMap))
assert.Equal(t, "the domain of user email user2@example1.com conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", errMap["message"])
originalEmail := "user2@example.org"
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
LoginName: "user2",
SourceID: 0,
Email: &originalEmail,
}).AddTokenAuth(token)
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{Email: new("user2@example.org")}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)
}