Skip to content

Commit f60a40e

Browse files
committed
Never use /api/v1 from Gitea UI Pages
1 parent bb7e061 commit f60a40e

27 files changed

+733
-72
lines changed

modules/context/api.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -191,22 +191,6 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) {
191191
}
192192
}
193193

194-
// SetTotalCountHeader set "X-Total-Count" header
195-
func (ctx *APIContext) SetTotalCountHeader(total int64) {
196-
ctx.RespHeader().Set("X-Total-Count", fmt.Sprint(total))
197-
ctx.AppendAccessControlExposeHeaders("X-Total-Count")
198-
}
199-
200-
// AppendAccessControlExposeHeaders append headers by name to "Access-Control-Expose-Headers" header
201-
func (ctx *APIContext) AppendAccessControlExposeHeaders(names ...string) {
202-
val := ctx.RespHeader().Get("Access-Control-Expose-Headers")
203-
if len(val) != 0 {
204-
ctx.RespHeader().Set("Access-Control-Expose-Headers", fmt.Sprintf("%s, %s", val, strings.Join(names, ", ")))
205-
} else {
206-
ctx.RespHeader().Set("Access-Control-Expose-Headers", strings.Join(names, ", "))
207-
}
208-
}
209-
210194
// RequireCSRF requires a validated a CSRF token
211195
func (ctx *APIContext) RequireCSRF() {
212196
headerToken := ctx.Req.Header.Get(ctx.csrf.GetHeaderName())

modules/context/context.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"crypto/sha256"
1111
"encoding/hex"
1212
"errors"
13+
"fmt"
1314
"html"
1415
"html/template"
1516
"io"
@@ -21,6 +22,7 @@ import (
2122
"strings"
2223
"time"
2324

25+
"code.gitea.io/gitea/models/db"
2426
"code.gitea.io/gitea/models/unit"
2527
user_model "code.gitea.io/gitea/models/user"
2628
"code.gitea.io/gitea/modules/base"
@@ -577,6 +579,22 @@ func (ctx *Context) Value(key interface{}) interface{} {
577579
return ctx.Req.Context().Value(key)
578580
}
579581

582+
// SetTotalCountHeader set "X-Total-Count" header
583+
func (ctx *Context) SetTotalCountHeader(total int64) {
584+
ctx.RespHeader().Set("X-Total-Count", fmt.Sprint(total))
585+
ctx.AppendAccessControlExposeHeaders("X-Total-Count")
586+
}
587+
588+
// AppendAccessControlExposeHeaders append headers by name to "Access-Control-Expose-Headers" header
589+
func (ctx *Context) AppendAccessControlExposeHeaders(names ...string) {
590+
val := ctx.RespHeader().Get("Access-Control-Expose-Headers")
591+
if len(val) != 0 {
592+
ctx.RespHeader().Set("Access-Control-Expose-Headers", fmt.Sprintf("%s, %s", val, strings.Join(names, ", ")))
593+
} else {
594+
ctx.RespHeader().Set("Access-Control-Expose-Headers", strings.Join(names, ", "))
595+
}
596+
}
597+
580598
// Handler represents a custom handler
581599
type Handler func(*Context)
582600

@@ -780,3 +798,21 @@ func Contexter() func(next http.Handler) http.Handler {
780798
})
781799
}
782800
}
801+
802+
// SearchOrderByMap represents all possible search order
803+
var SearchOrderByMap = map[string]map[string]db.SearchOrderBy{
804+
"asc": {
805+
"alpha": db.SearchOrderByAlphabetically,
806+
"created": db.SearchOrderByOldest,
807+
"updated": db.SearchOrderByLeastUpdated,
808+
"size": db.SearchOrderBySize,
809+
"id": db.SearchOrderByID,
810+
},
811+
"desc": {
812+
"alpha": db.SearchOrderByAlphabeticallyReverse,
813+
"created": db.SearchOrderByNewest,
814+
"updated": db.SearchOrderByRecentUpdated,
815+
"size": db.SearchOrderBySizeReverse,
816+
"id": db.SearchOrderByIDReverse,
817+
},
818+
}

routers/api/v1/utils/utils.go renamed to modules/context/utils.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,16 @@
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

5-
package utils
5+
package context
66

77
import (
88
"net/url"
99
"strings"
1010
"time"
11-
12-
"code.gitea.io/gitea/models/db"
13-
"code.gitea.io/gitea/modules/context"
14-
"code.gitea.io/gitea/modules/convert"
1511
)
1612

1713
// GetQueryBeforeSince return parsed time (unix format) from URL query's before and since
18-
func GetQueryBeforeSince(ctx *context.APIContext) (before, since int64, err error) {
14+
func GetQueryBeforeSince(ctx *Context) (before, since int64, err error) {
1915
qCreatedBefore, err := prepareQueryArg(ctx, "before")
2016
if err != nil {
2117
return 0, 0, err
@@ -53,16 +49,8 @@ func parseTime(value string) (int64, error) {
5349
}
5450

5551
// prepareQueryArg unescape and trim a query arg
56-
func prepareQueryArg(ctx *context.APIContext, name string) (value string, err error) {
52+
func prepareQueryArg(ctx *Context, name string) (value string, err error) {
5753
value, err = url.PathUnescape(ctx.FormString(name))
5854
value = strings.TrimSpace(value)
5955
return
6056
}
61-
62-
// GetListOptions returns list options using the page and limit parameters
63-
func GetListOptions(ctx *context.APIContext) db.ListOptions {
64-
return db.ListOptions{
65-
Page: ctx.FormInt("page"),
66-
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
67-
}
68-
}

routers/api/v1/notify/notifications.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func NewAvailable(ctx *context.APIContext) {
2626
}
2727

2828
func getFindNotificationOptions(ctx *context.APIContext) *models.FindNotificationOptions {
29-
before, since, err := utils.GetQueryBeforeSince(ctx)
29+
before, since, err := context.GetQueryBeforeSince(ctx.Context)
3030
if err != nil {
3131
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
3232
return nil

routers/api/v1/repo/issue.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func SearchIssues(ctx *context.APIContext) {
111111
// "200":
112112
// "$ref": "#/responses/IssueList"
113113

114-
before, since, err := utils.GetQueryBeforeSince(ctx)
114+
before, since, err := context.GetQueryBeforeSince(ctx.Context)
115115
if err != nil {
116116
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
117117
return
@@ -359,7 +359,7 @@ func ListIssues(ctx *context.APIContext) {
359359
// responses:
360360
// "200":
361361
// "$ref": "#/responses/IssueList"
362-
before, since, err := utils.GetQueryBeforeSince(ctx)
362+
before, since, err := context.GetQueryBeforeSince(ctx.Context)
363363
if err != nil {
364364
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
365365
return

routers/api/v1/repo/issue_comment.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func ListIssueComments(ctx *context.APIContext) {
5858
// "200":
5959
// "$ref": "#/responses/CommentList"
6060

61-
before, since, err := utils.GetQueryBeforeSince(ctx)
61+
before, since, err := context.GetQueryBeforeSince(ctx.Context)
6262
if err != nil {
6363
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
6464
return
@@ -150,7 +150,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
150150
// "200":
151151
// "$ref": "#/responses/TimelineList"
152152

153-
before, since, err := utils.GetQueryBeforeSince(ctx)
153+
before, since, err := context.GetQueryBeforeSince(ctx.Context)
154154
if err != nil {
155155
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
156156
return
@@ -253,7 +253,7 @@ func ListRepoIssueComments(ctx *context.APIContext) {
253253
// "200":
254254
// "$ref": "#/responses/CommentList"
255255

256-
before, since, err := utils.GetQueryBeforeSince(ctx)
256+
before, since, err := context.GetQueryBeforeSince(ctx.Context)
257257
if err != nil {
258258
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
259259
return

routers/api/v1/repo/issue_tracked_time.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
103103
opts.UserID = user.ID
104104
}
105105

106-
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil {
106+
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Context); err != nil {
107107
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
108108
return
109109
}
@@ -522,7 +522,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
522522
}
523523

524524
var err error
525-
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil {
525+
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Context); err != nil {
526526
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
527527
return
528528
}
@@ -597,7 +597,7 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
597597
}
598598

599599
var err error
600-
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil {
600+
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Context); err != nil {
601601
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
602602
return
603603
}

routers/api/v1/repo/repo.go

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,6 @@ import (
3131
repo_service "code.gitea.io/gitea/services/repository"
3232
)
3333

34-
var searchOrderByMap = map[string]map[string]db.SearchOrderBy{
35-
"asc": {
36-
"alpha": db.SearchOrderByAlphabetically,
37-
"created": db.SearchOrderByOldest,
38-
"updated": db.SearchOrderByLeastUpdated,
39-
"size": db.SearchOrderBySize,
40-
"id": db.SearchOrderByID,
41-
},
42-
"desc": {
43-
"alpha": db.SearchOrderByAlphabeticallyReverse,
44-
"created": db.SearchOrderByNewest,
45-
"updated": db.SearchOrderByRecentUpdated,
46-
"size": db.SearchOrderBySizeReverse,
47-
"id": db.SearchOrderByIDReverse,
48-
},
49-
}
50-
5134
// Search repositories via options
5235
func Search(ctx *context.APIContext) {
5336
// swagger:operation GET /repos/search repository repoSearch
@@ -193,7 +176,7 @@ func Search(ctx *context.APIContext) {
193176
if len(sortOrder) == 0 {
194177
sortOrder = "asc"
195178
}
196-
if searchModeMap, ok := searchOrderByMap[sortOrder]; ok {
179+
if searchModeMap, ok := context.SearchOrderByMap[sortOrder]; ok {
197180
if orderBy, ok := searchModeMap[sortMode]; ok {
198181
opts.OrderBy = orderBy
199182
} else {

routers/api/v1/utils/page.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2017 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package utils
6+
7+
import (
8+
"code.gitea.io/gitea/models/db"
9+
"code.gitea.io/gitea/modules/context"
10+
"code.gitea.io/gitea/modules/convert"
11+
)
12+
13+
// GetListOptions returns list options using the page and limit parameters
14+
func GetListOptions(ctx *context.APIContext) db.ListOptions {
15+
return db.ListOptions{
16+
Page: ctx.FormInt("page"),
17+
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
18+
}
19+
}

routers/web/explore/topic.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package explore
6+
7+
import (
8+
"net/http"
9+
10+
"code.gitea.io/gitea/models/db"
11+
repo_model "code.gitea.io/gitea/models/repo"
12+
"code.gitea.io/gitea/modules/context"
13+
"code.gitea.io/gitea/modules/convert"
14+
api "code.gitea.io/gitea/modules/structs"
15+
)
16+
17+
// TopicSearch search for creating topic
18+
func TopicSearch(ctx *context.Context) {
19+
opts := &repo_model.FindTopicOptions{
20+
Keyword: ctx.FormString("q"),
21+
ListOptions: db.ListOptions{
22+
Page: ctx.FormInt("page"),
23+
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
24+
},
25+
}
26+
27+
topics, total, err := repo_model.FindTopics(opts)
28+
if err != nil {
29+
ctx.Error(http.StatusInternalServerError)
30+
return
31+
}
32+
33+
topicResponses := make([]*api.TopicResponse, len(topics))
34+
for i, topic := range topics {
35+
topicResponses[i] = convert.ToTopicResponse(topic)
36+
}
37+
38+
ctx.SetTotalCountHeader(total)
39+
ctx.JSON(http.StatusOK, map[string]interface{}{
40+
"topics": topicResponses,
41+
})
42+
}

routers/web/org/teams.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ import (
1313
"strings"
1414

1515
"code.gitea.io/gitea/models"
16+
"code.gitea.io/gitea/models/db"
1617
"code.gitea.io/gitea/models/organization"
1718
"code.gitea.io/gitea/models/perm"
1819
repo_model "code.gitea.io/gitea/models/repo"
1920
unit_model "code.gitea.io/gitea/models/unit"
2021
user_model "code.gitea.io/gitea/models/user"
2122
"code.gitea.io/gitea/modules/base"
2223
"code.gitea.io/gitea/modules/context"
24+
"code.gitea.io/gitea/modules/convert"
2325
"code.gitea.io/gitea/modules/log"
26+
api "code.gitea.io/gitea/modules/structs"
2427
"code.gitea.io/gitea/modules/web"
2528
"code.gitea.io/gitea/routers/utils"
2629
"code.gitea.io/gitea/services/forms"
@@ -329,6 +332,51 @@ func TeamRepositories(ctx *context.Context) {
329332
ctx.HTML(http.StatusOK, tplTeamRepositories)
330333
}
331334

335+
// SearchTeam api for searching teams
336+
func SearchTeam(ctx *context.Context) {
337+
listOptions := db.ListOptions{
338+
Page: ctx.FormInt("page"),
339+
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
340+
}
341+
342+
opts := &organization.SearchTeamOptions{
343+
UserID: ctx.Doer.ID,
344+
Keyword: ctx.FormTrim("q"),
345+
OrgID: ctx.Org.Organization.ID,
346+
IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"),
347+
ListOptions: listOptions,
348+
}
349+
350+
teams, maxResults, err := organization.SearchTeam(opts)
351+
if err != nil {
352+
log.Error("SearchTeam failed: %v", err)
353+
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
354+
"ok": false,
355+
"error": "SearchTeam internal failure",
356+
})
357+
return
358+
}
359+
360+
apiTeams := make([]*api.Team, len(teams))
361+
for i := range teams {
362+
if err := teams[i].GetUnits(); err != nil {
363+
log.Error("Team GetUnits failed: %v", err)
364+
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
365+
"ok": false,
366+
"error": "SearchTeam failed to get units",
367+
})
368+
return
369+
}
370+
apiTeams[i] = convert.ToTeam(teams[i])
371+
}
372+
373+
ctx.SetTotalCountHeader(maxResults)
374+
ctx.JSON(http.StatusOK, map[string]interface{}{
375+
"ok": true,
376+
"data": apiTeams,
377+
})
378+
}
379+
332380
// EditTeam render team edit page
333381
func EditTeam(ctx *context.Context) {
334382
ctx.Data["Title"] = ctx.Org.Organization.FullName

0 commit comments

Comments
 (0)