Skip to content

Commit 5a1e12d

Browse files
committed
Refactor find forks and fix possible bugs that weak permissions check
1 parent e546480 commit 5a1e12d

File tree

6 files changed

+65
-39
lines changed

6 files changed

+65
-39
lines changed

models/repo/fork.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,6 @@ func GetUserFork(ctx context.Context, repoID, userID int64) (*Repository, error)
5454
return &forkedRepo, nil
5555
}
5656

57-
// GetForks returns all the forks of the repository
58-
func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions) ([]*Repository, error) {
59-
sess := db.GetEngine(ctx)
60-
61-
var forks []*Repository
62-
if listOptions.Page == 0 {
63-
forks = make([]*Repository, 0, repo.NumForks)
64-
} else {
65-
forks = make([]*Repository, 0, listOptions.PageSize)
66-
sess = db.SetSessionPagination(sess, &listOptions)
67-
}
68-
69-
return forks, sess.Find(&forks, &Repository{ForkID: repo.ID})
70-
}
71-
7257
// IncrementRepoForkNum increment repository fork number
7358
func IncrementRepoForkNum(ctx context.Context, repoID int64) error {
7459
_, err := db.GetEngine(ctx).Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", repoID)

models/repo/repo_list.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,14 @@ func (repos RepositoryList) IDs() []int64 {
9898
return repoIDs
9999
}
100100

101-
// LoadAttributes loads the attributes for the given RepositoryList
102-
func (repos RepositoryList) LoadAttributes(ctx context.Context) error {
101+
func (repos RepositoryList) LoadOwners(ctx context.Context) error {
103102
if len(repos) == 0 {
104103
return nil
105104
}
106105

107106
userIDs := container.FilterSlice(repos, func(repo *Repository) (int64, bool) {
108107
return repo.OwnerID, true
109108
})
110-
repoIDs := make([]int64, len(repos))
111-
for i := range repos {
112-
repoIDs[i] = repos[i].ID
113-
}
114109

115110
// Load owners.
116111
users := make(map[int64]*user_model.User, len(userIDs))
@@ -123,12 +118,19 @@ func (repos RepositoryList) LoadAttributes(ctx context.Context) error {
123118
for i := range repos {
124119
repos[i].Owner = users[repos[i].OwnerID]
125120
}
121+
return nil
122+
}
123+
124+
func (repos RepositoryList) LoadLanguageStats(ctx context.Context) error {
125+
if len(repos) == 0 {
126+
return nil
127+
}
126128

127129
// Load primary language.
128130
stats := make(LanguageStatList, 0, len(repos))
129131
if err := db.GetEngine(ctx).
130132
Where("`is_primary` = ? AND `language` != ?", true, "other").
131-
In("`repo_id`", repoIDs).
133+
In("`repo_id`", repos.IDs()).
132134
Find(&stats); err != nil {
133135
return fmt.Errorf("find primary languages: %w", err)
134136
}
@@ -141,10 +143,18 @@ func (repos RepositoryList) LoadAttributes(ctx context.Context) error {
141143
}
142144
}
143145
}
144-
145146
return nil
146147
}
147148

149+
// LoadAttributes loads the attributes for the given RepositoryList
150+
func (repos RepositoryList) LoadAttributes(ctx context.Context) error {
151+
if err := repos.LoadOwners(ctx); err != nil {
152+
return err
153+
}
154+
155+
return repos.LoadLanguageStats(ctx)
156+
}
157+
148158
// SearchRepoOptions holds the search options
149159
type SearchRepoOptions struct {
150160
db.ListOptions

routers/api/v1/repo/fork.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,20 @@ func ListForks(ctx *context.APIContext) {
5555
// "404":
5656
// "$ref": "#/responses/notFound"
5757

58-
forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx))
58+
forks, total, err := repo_service.FindForks(ctx, ctx.Repo.Repository, ctx.Doer, utils.GetListOptions(ctx))
5959
if err != nil {
60-
ctx.Error(http.StatusInternalServerError, "GetForks", err)
60+
ctx.Error(http.StatusInternalServerError, "FindForks", err)
6161
return
6262
}
63+
if err := repo_model.RepositoryList(forks).LoadOwners(ctx); err != nil {
64+
ctx.Error(http.StatusInternalServerError, "LoadOwners", err)
65+
return
66+
}
67+
if err := repo_model.RepositoryList(forks).LoadUnits(ctx); err != nil {
68+
ctx.Error(http.StatusInternalServerError, "LoadUnits", err)
69+
return
70+
}
71+
6372
apiForks := make([]*api.Repository, len(forks))
6473
for i, fork := range forks {
6574
permission, err := access_model.GetUserRepoPermission(ctx, fork, ctx.Doer)
@@ -70,7 +79,7 @@ func ListForks(ctx *context.APIContext) {
7079
apiForks[i] = convert.ToRepo(ctx, fork, permission)
7180
}
7281

73-
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumForks))
82+
ctx.SetTotalCountHeader(total)
7483
ctx.JSON(http.StatusOK, apiForks)
7584
}
7685

routers/web/repo/view.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,26 +1151,25 @@ func Forks(ctx *context.Context) {
11511151
if page <= 0 {
11521152
page = 1
11531153
}
1154+
pageSize := setting.ItemsPerPage
11541155

1155-
pager := context.NewPagination(ctx.Repo.Repository.NumForks, setting.ItemsPerPage, page, 5)
1156-
ctx.Data["Page"] = pager
1157-
1158-
forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, db.ListOptions{
1159-
Page: pager.Paginater.Current(),
1160-
PageSize: setting.ItemsPerPage,
1156+
forks, total, err := repo_service.FindForks(ctx, ctx.Repo.Repository, ctx.Doer, db.ListOptions{
1157+
Page: page,
1158+
PageSize: pageSize,
11611159
})
11621160
if err != nil {
1163-
ctx.ServerError("GetForks", err)
1161+
ctx.ServerError("FindForks", err)
11641162
return
11651163
}
11661164

1167-
for _, fork := range forks {
1168-
if err = fork.LoadOwner(ctx); err != nil {
1169-
ctx.ServerError("LoadOwner", err)
1170-
return
1171-
}
1165+
if err := repo_model.RepositoryList(forks).LoadOwners(ctx); err != nil {
1166+
ctx.ServerError("LoadAttributes", err)
1167+
return
11721168
}
11731169

1170+
pager := context.NewPagination(int(total), pageSize, page, 5)
1171+
ctx.Data["Page"] = pager
1172+
11741173
ctx.Data["Forks"] = forks
11751174

11761175
ctx.HTML(http.StatusOK, tplForks)

services/mirror/mirror_pull.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
307307
output := stderrBuilder.String()
308308

309309
if err := git.WriteCommitGraph(ctx, repoPath); err != nil {
310-
log.Error("SyncMirrors [repo: %-v]: %v", m.Repo, err)
310+
log.Error("SyncMirrors: WriteCommitGraph [repo: %-v]: %v", m.Repo, err)
311311
}
312312

313313
gitRepo, err := gitrepo.OpenRepository(ctx, m.Repo)

services/repository/fork.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"code.gitea.io/gitea/models/db"
1313
git_model "code.gitea.io/gitea/models/git"
1414
repo_model "code.gitea.io/gitea/models/repo"
15+
"code.gitea.io/gitea/models/unit"
1516
user_model "code.gitea.io/gitea/models/user"
1617
"code.gitea.io/gitea/modules/git"
1718
"code.gitea.io/gitea/modules/gitrepo"
@@ -20,6 +21,7 @@ import (
2021
"code.gitea.io/gitea/modules/structs"
2122
"code.gitea.io/gitea/modules/util"
2223
notify_service "code.gitea.io/gitea/services/notify"
24+
"xorm.io/builder"
2325
)
2426

2527
// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error.
@@ -247,3 +249,24 @@ func ConvertForkToNormalRepository(ctx context.Context, repo *repo_model.Reposit
247249

248250
return err
249251
}
252+
253+
type findForksOptions struct {
254+
db.ListOptions
255+
RepoID int64
256+
Doer *user_model.User
257+
}
258+
259+
func (opts findForksOptions) ToConds() builder.Cond {
260+
return builder.Eq{"fork_id": opts.RepoID}.And(
261+
repo_model.AccessibleRepositoryCondition(opts.Doer, unit.TypeInvalid),
262+
)
263+
}
264+
265+
// FindForks returns all the forks of the repository
266+
func FindForks(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, listOptions db.ListOptions) ([]*repo_model.Repository, int64, error) {
267+
return db.FindAndCount[repo_model.Repository](ctx, findForksOptions{
268+
ListOptions: listOptions,
269+
RepoID: repo.ID,
270+
Doer: doer,
271+
})
272+
}

0 commit comments

Comments
 (0)