From cbcf36cded84648cbbeeab091a6fede3ea7e1a62 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 16 Aug 2026 07:03:57 -0700 Subject: [PATCH] fix: make "login_name" field optional for API edit user (#38917) (#38945) Backport #38917 Co-authored-by: wxiaoguang --- modules/structs/admin_user.go | 5 +--- modules/structs/user.go | 1 - routers/api/v1/admin/user.go | 2 +- templates/swagger/v1_json.tmpl | 6 +---- templates/swagger/v1_openapi3_json.tmpl | 6 +---- tests/integration/api_admin_test.go | 32 ++++--------------------- 6 files changed, 9 insertions(+), 43 deletions(-) diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go index ee65e016bcd..4fe976b3507 100644 --- a/modules/structs/admin_user.go +++ b/modules/structs/admin_user.go @@ -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)"` diff --git a/modules/structs/user.go b/modules/structs/user.go index 852d2c4bdd4..14f317ba2cd 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -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"` diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 9441fe0c18e..aaaf4e4a80f 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -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), diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 7735ecb4b4b..62e60f88c19 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -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": { diff --git a/templates/swagger/v1_openapi3_json.tmpl b/templates/swagger/v1_openapi3_json.tmpl index 2f817c207ac..3566aae6f69 100644 --- a/templates/swagger/v1_openapi3_json.tmpl +++ b/templates/swagger/v1_openapi3_json.tmpl @@ -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" diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index c02137a326b..349ab26c691 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -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) }