-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
API endpoint for searching teams. #8108
Changes from 12 commits
7cfa3d5
62c798f
ebecd5a
2476663
0f075c1
bfbc4ab
ff4520b
a1e1a9a
76a5901
30e014c
57bf392
0745ee4
e74347a
f1de2b1
a632034
03861f1
9704d49
b101793
4288527
8755739
fc66f6a
b31fc41
5785acd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import ( | |
"code.gitea.io/gitea/modules/setting" | ||
|
||
"github.com/go-xorm/xorm" | ||
"xorm.io/builder" | ||
) | ||
|
||
const ownerTeamName = "Owners" | ||
|
@@ -34,6 +35,64 @@ type Team struct { | |
Units []*TeamUnit `xorm:"-"` | ||
} | ||
|
||
// SearchTeamOptions holds the search options | ||
type SearchTeamOptions struct { | ||
UserID int64 | ||
UserIsAdmin bool | ||
Keyword string | ||
OrgID int64 | ||
IncludeDesc bool | ||
Limit int | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't check other API endpoints, but isn't it a bit strange to limit the query while not supporting pagination? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pagination added to the API. |
||
} | ||
|
||
// SearchTeam search for teams. Caller is responsible to check permissions. | ||
func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { | ||
if opts.Limit <= 0 { | ||
opts.Limit = 10 | ||
} | ||
var cond = builder.NewCond() | ||
|
||
if len(opts.Keyword) > 0 { | ||
lowerKeyword := strings.ToLower(opts.Keyword) | ||
var keywordCond = builder.NewCond() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. var keywordCond = builder.Like{"lower_name"}
if opts.IncludeDesc {
keywordCond = keywordCond.Or(builder.Like{"LOWER(description)", lowerKeyword})
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, ran out of laptop battery before I could finish properly. Will fix later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I think I got it right. |
||
if opts.IncludeDesc { | ||
keywordCond = builder.Or( | ||
builder.Like{"lower_name", lowerKeyword}, | ||
builder.Like{"LOWER(description)", lowerKeyword}, | ||
) | ||
} else { | ||
keywordCond = builder.Or( | ||
builder.Like{"lower_name", lowerKeyword}, | ||
) | ||
} | ||
cond = cond.And(keywordCond) | ||
} | ||
|
||
cond = cond.And(builder.Eq{"org_id": opts.OrgID}) | ||
|
||
sess := x.NewSession() | ||
defer sess.Close() | ||
|
||
count, err := sess. | ||
Where(cond). | ||
Count(new(Team)) | ||
|
||
if err != nil { | ||
return nil, 0, err | ||
} | ||
|
||
teams := make([]*Team, 0, opts.Limit) | ||
if err = sess. | ||
Where(cond). | ||
OrderBy("lower_name"). | ||
Limit(opts.Limit). | ||
Find(&teams); err != nil { | ||
return nil, 0, err | ||
} | ||
|
||
return teams, count, nil | ||
} | ||
|
||
// ColorFormat provides a basic color format for a Team | ||
func (t *Team) ColorFormat(s fmt.State) { | ||
log.ColorFprintf(s, "%d:%s (OrgID: %d) %-v", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,11 @@ | |
package org | ||
|
||
import ( | ||
"strings" | ||
|
||
"code.gitea.io/gitea/models" | ||
"code.gitea.io/gitea/modules/context" | ||
"code.gitea.io/gitea/modules/log" | ||
api "code.gitea.io/gitea/modules/structs" | ||
"code.gitea.io/gitea/routers/api/v1/convert" | ||
"code.gitea.io/gitea/routers/api/v1/user" | ||
|
@@ -504,3 +507,79 @@ func RemoveTeamRepository(ctx *context.APIContext) { | |
} | ||
ctx.Status(204) | ||
} | ||
|
||
// SearchTeam api for searching teams | ||
func SearchTeam(ctx *context.APIContext) { | ||
// swagger:operation GET /orgs/{org}/teams/search organization teamSearch | ||
// --- | ||
// summary: Search for teams within an organization | ||
// produces: | ||
// - application/json | ||
// parameters: | ||
// - name: org | ||
// in: path | ||
// description: name of the organization | ||
// type: string | ||
// required: true | ||
// - name: q | ||
// in: query | ||
// description: keywords to search | ||
// type: string | ||
// - name: inclDesc | ||
// in: query | ||
// description: include search within team description (defaults to true) | ||
// type: boolean | ||
// - name: limit | ||
// in: query | ||
// description: limit size of results | ||
// type: integer | ||
// responses: | ||
// "200": | ||
// description: "SearchResults of a successful search" | ||
// schema: | ||
// type: object | ||
// properties: | ||
// ok: | ||
// type: boolean | ||
// data: | ||
// type: array | ||
// items: | ||
// "$ref": "#/definitions/Team" | ||
opts := &models.SearchTeamOptions{ | ||
UserID: ctx.Data["SignedUserID"].(int64), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
UserIsAdmin: ctx.IsUserSiteAdmin(), | ||
Keyword: strings.Trim(ctx.Query("q"), " "), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
OrgID: ctx.Org.Organization.ID, | ||
IncludeDesc: (ctx.Query("inclDesc") == "" || ctx.QueryBool("inclDesc")), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe |
||
Limit: ctx.QueryInt("limit"), | ||
} | ||
|
||
teams, _, err := models.SearchTeam(opts) | ||
if err != nil { | ||
log.Error("SearchTeam failed: %v", err) | ||
ctx.JSON(500, map[string]interface{}{ | ||
"ok": false, | ||
"error": "SearchTeam internal failure", | ||
}) | ||
return | ||
} | ||
|
||
apiTeams := make([]*api.Team, len(teams)) | ||
for i := range teams { | ||
if err := teams[i].GetUnits(); err != nil { | ||
log.Error("Team GetUnits failed: %v", err) | ||
ctx.JSON(500, map[string]interface{}{ | ||
"ok": false, | ||
"error": "SearchTeam failed to get units", | ||
}) | ||
return | ||
} | ||
apiTeams[i] = convert.ToTeam(teams[i]) | ||
} | ||
|
||
ctx.JSON(200, map[string]interface{}{ | ||
"ok": true, | ||
"data": apiTeams, | ||
}) | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserIsAdmin
is not used? I guess the router takes care of the permissions, but why is it here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed