1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

add user rename endpoint to admin api (#22789)

this is a simple endpoint that adds the ability to rename users to the
admin API.

Note: this is not in a mergeable state. It would be better if this was
handled by a PATCH/POST to the /api/v1/admin/users/{username} endpoint
and the username is modified.

---------

Co-authored-by: Jason Song <i@wolfogre.com>
This commit is contained in:
techknowlogick
2023-03-14 03:45:21 -04:00
committed by GitHub
parent aac07d010f
commit 03591f0f95
12 changed files with 206 additions and 44 deletions

View File

@@ -461,3 +461,61 @@ func GetAllUsers(ctx *context.APIContext) {
ctx.SetTotalCountHeader(maxResults)
ctx.JSON(http.StatusOK, &results)
}
// RenameUser api for renaming a user
func RenameUser(ctx *context.APIContext) {
// swagger:operation POST /admin/users/{username}/rename admin adminRenameUser
// ---
// summary: Rename a user
// produces:
// - application/json
// parameters:
// - name: username
// in: path
// description: existing username of user
// type: string
// required: true
// - name: body
// in: body
// required: true
// schema:
// "$ref": "#/definitions/RenameUserOption"
// responses:
// "204":
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
if ctx.ContextUser.IsOrganization() {
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name))
return
}
newName := web.GetForm(ctx).(*api.RenameUserOption).NewName
if strings.EqualFold(newName, ctx.ContextUser.Name) {
// Noop as username is not changed
ctx.Status(http.StatusNoContent)
return
}
// Check if user name has been changed
if err := user_service.RenameUser(ctx, ctx.ContextUser, newName); err != nil {
switch {
case user_model.IsErrUserAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.username_been_taken"))
case db.IsErrNameReserved(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_reserved", newName))
case db.IsErrNamePatternNotAllowed(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_pattern_not_allowed", newName))
case db.IsErrNameCharsNotAllowed(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_chars_not_allowed", newName))
default:
ctx.ServerError("ChangeUserName", err)
}
return
}
ctx.Status(http.StatusNoContent)
}

View File

@@ -1257,6 +1257,7 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Get("/orgs", org.ListUserOrgs)
m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo)
m.Post("/rename", bind(api.RenameUserOption{}), admin.RenameUser)
}, context_service.UserAssignmentAPI())
})
m.Group("/unadopted", func() {

View File

@@ -48,6 +48,9 @@ type swaggerParameterBodies struct {
// in:body
CreateKeyOption api.CreateKeyOption
// in:body
RenameUserOption api.RenameUserOption
// in:body
CreateLabelOption api.CreateLabelOption
// in:body

View File

@@ -79,7 +79,7 @@ func SettingsPost(ctx *context.Context) {
ctx.Data["OrgName"] = true
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), tplSettingsOptions, &form)
return
} else if err = user_model.ChangeUserName(org.AsUser(), form.Name); err != nil {
} else if err = user_model.ChangeUserName(ctx, org.AsUser(), form.Name); err != nil {
switch {
case db.IsErrNameReserved(err):
ctx.Data["OrgName"] = true

View File

@@ -27,9 +27,7 @@ import (
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/agit"
"code.gitea.io/gitea/services/forms"
container_service "code.gitea.io/gitea/services/packages/container"
user_service "code.gitea.io/gitea/services/user"
)
@@ -57,45 +55,25 @@ func HandleUsernameChange(ctx *context.Context, user *user_model.User, newName s
return fmt.Errorf(ctx.Tr("form.username_change_not_local_user"))
}
// Check if user name has been changed
if user.LowerName != strings.ToLower(newName) {
if err := user_model.ChangeUserName(user, newName); err != nil {
switch {
case user_model.IsErrUserAlreadyExist(err):
ctx.Flash.Error(ctx.Tr("form.username_been_taken"))
case user_model.IsErrEmailAlreadyUsed(err):
ctx.Flash.Error(ctx.Tr("form.email_been_used"))
case db.IsErrNameReserved(err):
ctx.Flash.Error(ctx.Tr("user.form.name_reserved", newName))
case db.IsErrNamePatternNotAllowed(err):
ctx.Flash.Error(ctx.Tr("user.form.name_pattern_not_allowed", newName))
case db.IsErrNameCharsNotAllowed(err):
ctx.Flash.Error(ctx.Tr("user.form.name_chars_not_allowed", newName))
default:
ctx.ServerError("ChangeUserName", err)
}
return err
// rename user
if err := user_service.RenameUser(ctx, user, newName); err != nil {
switch {
case user_model.IsErrUserAlreadyExist(err):
ctx.Flash.Error(ctx.Tr("form.username_been_taken"))
case user_model.IsErrEmailAlreadyUsed(err):
ctx.Flash.Error(ctx.Tr("form.email_been_used"))
case db.IsErrNameReserved(err):
ctx.Flash.Error(ctx.Tr("user.form.name_reserved", newName))
case db.IsErrNamePatternNotAllowed(err):
ctx.Flash.Error(ctx.Tr("user.form.name_pattern_not_allowed", newName))
case db.IsErrNameCharsNotAllowed(err):
ctx.Flash.Error(ctx.Tr("user.form.name_chars_not_allowed", newName))
default:
ctx.ServerError("ChangeUserName", err)
}
} else {
if err := repo_model.UpdateRepositoryOwnerNames(user.ID, newName); err != nil {
ctx.ServerError("UpdateRepository", err)
return err
}
}
// update all agit flow pull request header
err := agit.UserNameChanged(user, newName)
if err != nil {
ctx.ServerError("agit.UserNameChanged", err)
return err
}
if err := container_service.UpdateRepositoryNames(ctx, user, newName); err != nil {
ctx.ServerError("UpdateRepositoryNames", err)
return err
}
log.Trace("User name changed: %s -> %s", user.Name, newName)
return nil
}