mirror of
https://github.com/go-gitea/gitea.git
synced 2025-12-13 18:32:54 +00:00
Add sorting/filtering to admin user search API endpoint (#36112)
This commit is contained in:
@@ -18,6 +18,23 @@ import (
|
|||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AdminUserOrderByMap represents all possible admin user search orders
|
||||||
|
// This should only be used for admin API endpoints as we should not expose "updated" ordering which could expose recent user activity including logins.
|
||||||
|
var AdminUserOrderByMap = map[string]map[string]db.SearchOrderBy{
|
||||||
|
"asc": {
|
||||||
|
"name": db.SearchOrderByAlphabetically,
|
||||||
|
"created": db.SearchOrderByOldest,
|
||||||
|
"updated": db.SearchOrderByLeastUpdated,
|
||||||
|
"id": db.SearchOrderByID,
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
"name": db.SearchOrderByAlphabeticallyReverse,
|
||||||
|
"created": db.SearchOrderByNewest,
|
||||||
|
"updated": db.SearchOrderByRecentUpdated,
|
||||||
|
"id": db.SearchOrderByIDReverse,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// SearchUserOptions contains the options for searching
|
// SearchUserOptions contains the options for searching
|
||||||
type SearchUserOptions struct {
|
type SearchUserOptions struct {
|
||||||
db.ListOptions
|
db.ListOptions
|
||||||
|
|||||||
@@ -414,22 +414,116 @@ func SearchUsers(ctx *context.APIContext) {
|
|||||||
// in: query
|
// in: query
|
||||||
// description: page size of results
|
// description: page size of results
|
||||||
// type: integer
|
// type: integer
|
||||||
|
// - name: sort
|
||||||
|
// in: query
|
||||||
|
// description: sort users by attribute. Supported values are
|
||||||
|
// "name", "created", "updated" and "id".
|
||||||
|
// Default is "name"
|
||||||
|
// type: string
|
||||||
|
// - name: order
|
||||||
|
// in: query
|
||||||
|
// description: sort order, either "asc" (ascending) or "desc" (descending).
|
||||||
|
// Default is "asc", ignored if "sort" is not specified.
|
||||||
|
// type: string
|
||||||
|
// - name: q
|
||||||
|
// in: query
|
||||||
|
// description: search term (username, full name, email)
|
||||||
|
// type: string
|
||||||
|
// - name: visibility
|
||||||
|
// in: query
|
||||||
|
// description: visibility filter. Supported values are
|
||||||
|
// "public", "limited" and "private".
|
||||||
|
// type: string
|
||||||
|
// - name: is_active
|
||||||
|
// in: query
|
||||||
|
// description: filter active users
|
||||||
|
// type: boolean
|
||||||
|
// - name: is_admin
|
||||||
|
// in: query
|
||||||
|
// description: filter admin users
|
||||||
|
// type: boolean
|
||||||
|
// - name: is_restricted
|
||||||
|
// in: query
|
||||||
|
// description: filter restricted users
|
||||||
|
// type: boolean
|
||||||
|
// - name: is_2fa_enabled
|
||||||
|
// in: query
|
||||||
|
// description: filter 2FA enabled users
|
||||||
|
// type: boolean
|
||||||
|
// - name: is_prohibit_login
|
||||||
|
// in: query
|
||||||
|
// description: filter login prohibited users
|
||||||
|
// type: boolean
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/UserList"
|
// "$ref": "#/responses/UserList"
|
||||||
// "403":
|
// "403":
|
||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
|
// "422":
|
||||||
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
listOptions := utils.GetListOptions(ctx)
|
listOptions := utils.GetListOptions(ctx)
|
||||||
|
|
||||||
users, maxResults, err := user_model.SearchUsers(ctx, user_model.SearchUserOptions{
|
orderBy := db.SearchOrderByAlphabetically
|
||||||
|
sortMode := ctx.FormString("sort")
|
||||||
|
if len(sortMode) > 0 {
|
||||||
|
sortOrder := ctx.FormString("order")
|
||||||
|
if len(sortOrder) == 0 {
|
||||||
|
sortOrder = "asc"
|
||||||
|
}
|
||||||
|
if searchModeMap, ok := user_model.AdminUserOrderByMap[sortOrder]; ok {
|
||||||
|
if order, ok := searchModeMap[sortMode]; ok {
|
||||||
|
orderBy = order
|
||||||
|
} else {
|
||||||
|
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort mode: \"%s\"", sortMode))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort order: \"%s\"", sortOrder))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var visible []api.VisibleType
|
||||||
|
visibilityParam := ctx.FormString("visibility")
|
||||||
|
if len(visibilityParam) > 0 {
|
||||||
|
if visibility, ok := api.VisibilityModes[visibilityParam]; ok {
|
||||||
|
visible = []api.VisibleType{visibility}
|
||||||
|
} else {
|
||||||
|
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid visibility: \"%s\"", visibilityParam))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
searchOpts := user_model.SearchUserOptions{
|
||||||
Actor: ctx.Doer,
|
Actor: ctx.Doer,
|
||||||
Types: []user_model.UserType{user_model.UserTypeIndividual},
|
Types: []user_model.UserType{user_model.UserTypeIndividual},
|
||||||
LoginName: ctx.FormTrim("login_name"),
|
LoginName: ctx.FormTrim("login_name"),
|
||||||
SourceID: ctx.FormInt64("source_id"),
|
SourceID: ctx.FormInt64("source_id"),
|
||||||
OrderBy: db.SearchOrderByAlphabetically,
|
Keyword: ctx.FormTrim("q"),
|
||||||
|
Visible: visible,
|
||||||
|
OrderBy: orderBy,
|
||||||
ListOptions: listOptions,
|
ListOptions: listOptions,
|
||||||
})
|
SearchByEmail: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.FormString("is_active") != "" {
|
||||||
|
searchOpts.IsActive = optional.Some(ctx.FormBool("is_active"))
|
||||||
|
}
|
||||||
|
if ctx.FormString("is_admin") != "" {
|
||||||
|
searchOpts.IsAdmin = optional.Some(ctx.FormBool("is_admin"))
|
||||||
|
}
|
||||||
|
if ctx.FormString("is_restricted") != "" {
|
||||||
|
searchOpts.IsRestricted = optional.Some(ctx.FormBool("is_restricted"))
|
||||||
|
}
|
||||||
|
if ctx.FormString("is_2fa_enabled") != "" {
|
||||||
|
searchOpts.IsTwoFactorEnabled = optional.Some(ctx.FormBool("is_2fa_enabled"))
|
||||||
|
}
|
||||||
|
if ctx.FormString("is_prohibit_login") != "" {
|
||||||
|
searchOpts.IsProhibitLogin = optional.Some(ctx.FormBool("is_prohibit_login"))
|
||||||
|
}
|
||||||
|
|
||||||
|
users, maxResults, err := user_model.SearchUsers(ctx, searchOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.APIErrorInternal(err)
|
ctx.APIErrorInternal(err)
|
||||||
return
|
return
|
||||||
|
|||||||
57
templates/swagger/v1_json.tmpl
generated
57
templates/swagger/v1_json.tmpl
generated
@@ -781,6 +781,60 @@
|
|||||||
"description": "page size of results",
|
"description": "page size of results",
|
||||||
"name": "limit",
|
"name": "limit",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "sort users by attribute. Supported values are \"name\", \"created\", \"updated\" and \"id\". Default is \"name\"",
|
||||||
|
"name": "sort",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "sort order, either \"asc\" (ascending) or \"desc\" (descending). Default is \"asc\", ignored if \"sort\" is not specified.",
|
||||||
|
"name": "order",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "search term (username, full name, email)",
|
||||||
|
"name": "q",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "visibility filter. Supported values are \"public\", \"limited\" and \"private\".",
|
||||||
|
"name": "visibility",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "filter active users",
|
||||||
|
"name": "is_active",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "filter admin users",
|
||||||
|
"name": "is_admin",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "filter restricted users",
|
||||||
|
"name": "is_restricted",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "filter 2FA enabled users",
|
||||||
|
"name": "is_2fa_enabled",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "filter login prohibited users",
|
||||||
|
"name": "is_prohibit_login",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -789,6 +843,9 @@
|
|||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"$ref": "#/responses/forbidden"
|
"$ref": "#/responses/forbidden"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#/responses/validationError"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user