Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add user rename endpoint to admin api #22789

Merged
merged 27 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
363a51e
add user rename endpoint to admin api
techknowlogick Feb 6, 2023
9d010ef
Merge branch 'main' into rename-user-endpoint
techknowlogick Feb 20, 2023
6e37106
update swagger
techknowlogick Feb 21, 2023
b960b1f
fix swagger
techknowlogick Mar 2, 2023
87ccd60
fix swagger
techknowlogick Mar 2, 2023
ebe6a71
remove log debugging
techknowlogick Mar 2, 2023
e4b035f
Merge branch 'main' into rename-user-endpoint
techknowlogick Mar 9, 2023
83ac9e5
error will never be reached
techknowlogick Mar 9, 2023
d44c8e0
update swagger docs
techknowlogick Mar 9, 2023
5dd3a5f
move renameUser to service
techknowlogick Mar 9, 2023
cb84b4e
make fmt
techknowlogick Mar 9, 2023
2a1a46f
add newline to end of swagger template
techknowlogick Mar 9, 2023
df46a9f
move db into tx
techknowlogick Mar 9, 2023
e6437df
noop for no user change
techknowlogick Mar 9, 2023
8c71935
adds ctx back
techknowlogick Mar 9, 2023
07cc2ef
make lint
techknowlogick Mar 9, 2023
09d410e
add context
techknowlogick Mar 13, 2023
0d7542b
add context and move rename to service
techknowlogick Mar 13, 2023
599b318
Merge branch 'main' into rename-user-endpoint
techknowlogick Mar 13, 2023
621cd19
fix panic
techknowlogick Mar 13, 2023
e37edbd
Merge branch 'rename-user-endpoint' of github.com:techknowlogick/gite…
techknowlogick Mar 13, 2023
d53ea52
fix panic
techknowlogick Mar 13, 2023
5e9192b
unwrap error
techknowlogick Mar 13, 2023
f30a88d
remove duped code
techknowlogick Mar 14, 2023
9fbb7d8
Merge branch 'main' into rename-user-endpoint
techknowlogick Mar 14, 2023
259dbeb
Merge branch 'main' into rename-user-endpoint
techknowlogick Mar 14, 2023
79ed00f
Apply suggestions from code review
techknowlogick Mar 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions modules/structs/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@ type UserSettingsOptions struct {
HideEmail *bool `json:"hide_email"`
HideActivity *bool `json:"hide_activity"`
}

// CreateKeyOption options when creating a key
type RenameUserOption struct {
// New username
//
// required: true
// unique: true
NewName string `json:"new_username" binding:"Required"`
techknowlogick marked this conversation as resolved.
Show resolved Hide resolved
}
82 changes: 82 additions & 0 deletions routers/api/v1/admin/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/context"
Expand All @@ -25,9 +26,11 @@ import (
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/agit"
asymkey_service "code.gitea.io/gitea/services/asymkey"
"code.gitea.io/gitea/services/convert"
"code.gitea.io/gitea/services/mailer"
container_service "code.gitea.io/gitea/services/packages/container"
user_service "code.gitea.io/gitea/services/user"
)

Expand Down Expand Up @@ -457,3 +460,82 @@ 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
techknowlogick marked this conversation as resolved.
Show resolved Hide resolved
// Check if user name has been changed
if ctx.ContextUser.LowerName != strings.ToLower(newName) {
if err := user_model.ChangeUserName(ctx.ContextUser, newName); err != nil {
switch {
case user_model.IsErrUserAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.username_been_taken"))
case user_model.IsErrEmailAlreadyUsed(err):
techknowlogick marked this conversation as resolved.
Show resolved Hide resolved
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.email_been_used"))
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
}
} else {
if err := repo_model.UpdateRepositoryOwnerNames(ctx.ContextUser.ID, newName); err != nil {
ctx.ServerError("UpdateRepository", err)
return
}
}
// update all agit flow pull request header
err := agit.UserNameChanged(ctx.ContextUser, newName)
if err != nil {
ctx.ServerError("agit.UserNameChanged", err)
return
}
if err := container_service.UpdateRepositoryNames(ctx, ctx.ContextUser, newName); err != nil {
ctx.ServerError("UpdateRepositoryNames", err)
return
}

ctx.ContextUser.Name = newName
ctx.ContextUser.LowerName = strings.ToLower(newName)
if err := user_model.UpdateUser(ctx, ctx.ContextUser, false); err != nil {
ctx.ServerError("UpdateUser", err)
return
}

log.Trace("User name changed: %s -> %s", ctx.ContextUser.Name, newName)
ctx.Status(http.StatusNoContent)
}
1 change: 1 addition & 0 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,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)
techknowlogick marked this conversation as resolved.
Show resolved Hide resolved
}, context_service.UserAssignmentAPI())
})
m.Group("/unadopted", func() {
Expand Down
3 changes: 3 additions & 0 deletions routers/api/v1/swagger/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type swaggerParameterBodies struct {
// in:body
CreateKeyOption api.CreateKeyOption

// in:body
RenameUserOption api.RenameUserOption

// in:body
CreateLabelOption api.CreateLabelOption
// in:body
Expand Down
58 changes: 57 additions & 1 deletion templates/swagger/v1_json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,46 @@
}
}
},
"/admin/users/{username}/rename": {
"post": {
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Rename a user",
"operationId": "adminRenameUser",
"parameters": [
{
"type": "string",
"description": "existing username of user",
"name": "username",
"in": "path",
"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"
}
}
}
},
"/admin/users/{username}/repos": {
"post": {
"consumes": [
Expand Down Expand Up @@ -18921,6 +18961,22 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"RenameUserOption": {
"description": "CreateKeyOption options when creating a key",
techknowlogick marked this conversation as resolved.
Show resolved Hide resolved
"type": "object",
"required": [
"new_username"
],
"properties": {
"new_username": {
"description": "New username",
techknowlogick marked this conversation as resolved.
Show resolved Hide resolved
"type": "string",
"uniqueItems": true,
"x-go-name": "NewName"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"RepoCollaboratorPermission": {
"description": "RepoCollaboratorPermission to get repository permission for a collaborator",
"type": "object",
Expand Down Expand Up @@ -21020,4 +21076,4 @@
"TOTPHeader": []
}
]
}
}