[GITEA] enable system users search via the API

Refs: https://codeberg.org/forgejo/forgejo/issues/1403
(cherry picked from commit 87bd40411e)

Conflicts:
	routers/api/v1/user/user.go
	https://codeberg.org/forgejo/forgejo/pulls/1469
(cherry picked from commit 74f70ca873)
(cherry picked from commit 673a75bb43)
(cherry picked from commit fcd4535ac6)
(cherry picked from commit 56b229f22e)
(cherry picked from commit 45b922ae76)
This commit is contained in:
Earl Warren 2023-09-10 16:28:52 +02:00
parent 6d83f86cf0
commit 03805f3bf4
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
3 changed files with 51 additions and 13 deletions

View file

@ -9,10 +9,12 @@ import (
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
) )
const GhostUserID = -1
// NewGhostUser creates and returns a fake user for someone has deleted their account. // NewGhostUser creates and returns a fake user for someone has deleted their account.
func NewGhostUser() *User { func NewGhostUser() *User {
return &User{ return &User{
ID: -1, ID: GhostUserID,
Name: "Ghost", Name: "Ghost",
LowerName: "ghost", LowerName: "ghost",
} }

View file

@ -54,19 +54,33 @@ func Search(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx) listOptions := utils.GetListOptions(ctx)
users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{ uid := ctx.FormInt64("uid")
Actor: ctx.Doer, var users []*user_model.User
Keyword: ctx.FormTrim("q"), var maxResults int64
UID: ctx.FormInt64("uid"), var err error
Type: user_model.UserTypeIndividual,
ListOptions: listOptions, switch uid {
}) case user_model.GhostUserID:
if err != nil { maxResults = 1
ctx.JSON(http.StatusInternalServerError, map[string]any{ users = []*user_model.User{user_model.NewGhostUser()}
"ok": false, case user_model.ActionsUserID:
"error": err.Error(), maxResults = 1
users = []*user_model.User{user_model.NewActionsUser()}
default:
users, maxResults, err = user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer,
Keyword: ctx.FormTrim("q"),
UID: uid,
Type: user_model.UserTypeIndividual,
ListOptions: listOptions,
}) })
return if err != nil {
ctx.JSON(http.StatusInternalServerError, map[string]any{
"ok": false,
"error": err.Error(),
})
return
}
} }
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)

View file

@ -56,6 +56,28 @@ func TestAPIUserSearchNotLoggedIn(t *testing.T) {
} }
} }
func TestAPIUserSearchSystemUsers(t *testing.T) {
defer tests.PrepareTestEnv(t)()
for _, systemUser := range []*user_model.User{
user_model.NewGhostUser(),
user_model.NewActionsUser(),
} {
t.Run(systemUser.Name, func(t *testing.T) {
req := NewRequestf(t, "GET", "/api/v1/users/search?uid=%d", systemUser.ID)
resp := MakeRequest(t, req, http.StatusOK)
var results SearchResults
DecodeJSON(t, resp, &results)
assert.NotEmpty(t, results.Data)
if assert.EqualValues(t, 1, len(results.Data)) {
user := results.Data[0]
assert.EqualValues(t, user.UserName, systemUser.Name)
assert.EqualValues(t, user.ID, systemUser.ID)
}
})
}
}
func TestAPIUserSearchAdminLoggedInUserHidden(t *testing.T) { func TestAPIUserSearchAdminLoggedInUserHidden(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
adminUsername := "user1" adminUsername := "user1"