Skip to content

Commit 03d59bc

Browse files
davidsvantessontechknowlogick
authored andcommitted
Fix access issues on milestone and issue overview pages. (#9603)
* Fix access issues on milestone and issue overview pages. * Fix filter algorithm
1 parent 8b24073 commit 03d59bc

File tree

3 files changed

+63
-52
lines changed

3 files changed

+63
-52
lines changed

models/repo_permission.go

+20
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,23 @@ func hasAccess(e Engine, userID int64, repo *Repository) (bool, error) {
369369
func HasAccess(userID int64, repo *Repository) (bool, error) {
370370
return hasAccess(x, userID, repo)
371371
}
372+
373+
// FilterOutRepoIdsWithoutUnitAccess filter out repos where user has no access to repositories
374+
func FilterOutRepoIdsWithoutUnitAccess(u *User, repoIDs []int64, units ...UnitType) ([]int64, error) {
375+
i := 0
376+
for _, rID := range repoIDs {
377+
repo, err := GetRepositoryByID(rID)
378+
if err != nil {
379+
return nil, err
380+
}
381+
perm, err := GetUserRepoPermission(repo, u)
382+
if err != nil {
383+
return nil, err
384+
}
385+
if perm.CanReadAny(units...) {
386+
repoIDs[i] = rID
387+
i++
388+
}
389+
}
390+
return repoIDs[:i], nil
391+
}

models/user.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -638,19 +638,20 @@ func (u *User) GetRepositoryIDs(units ...UnitType) ([]int64, error) {
638638
func (u *User) GetOrgRepositoryIDs(units ...UnitType) ([]int64, error) {
639639
var ids []int64
640640

641-
sess := x.Table("repository").
641+
if err := x.Table("repository").
642642
Cols("repository.id").
643643
Join("INNER", "team_user", "repository.owner_id = team_user.org_id").
644-
Join("INNER", "team_repo", "repository.is_private != ? OR (team_user.team_id = team_repo.team_id AND repository.id = team_repo.repo_id)", true)
644+
Join("INNER", "team_repo", "repository.is_private != ? OR (team_user.team_id = team_repo.team_id AND repository.id = team_repo.repo_id)", true).
645+
Where("team_user.uid = ?", u.ID).
646+
GroupBy("repository.id").Find(&ids); err != nil {
647+
return nil, err
648+
}
645649

646650
if len(units) > 0 {
647-
sess = sess.Join("INNER", "team_unit", "team_unit.team_id = team_user.team_id")
648-
sess = sess.In("team_unit.type", units)
651+
return FilterOutRepoIdsWithoutUnitAccess(u, ids, units...)
649652
}
650653

651-
return ids, sess.
652-
Where("team_user.uid = ?", u.ID).
653-
GroupBy("repository.id").Find(&ids)
654+
return ids, nil
654655
}
655656

656657
// GetAccessRepoIDs returns all repositories IDs where user's or user is a team member organizations

routers/user/home.go

+35-45
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,13 @@ func Milestones(ctx *context.Context) {
188188
ctx.ServerError("env.RepoIDs", err)
189189
return
190190
}
191+
userRepoIDs, err = models.FilterOutRepoIdsWithoutUnitAccess(ctx.User, userRepoIDs, models.UnitTypeIssues, models.UnitTypePullRequests)
192+
if err != nil {
193+
ctx.ServerError("FilterOutRepoIdsWithoutUnitAccess", err)
194+
return
195+
}
191196
} else {
192-
unitType := models.UnitTypeIssues
193-
userRepoIDs, err = ctxUser.GetAccessRepoIDs(unitType)
197+
userRepoIDs, err = ctxUser.GetAccessRepoIDs(models.UnitTypeIssues, models.UnitTypePullRequests)
194198
if err != nil {
195199
ctx.ServerError("ctxUser.GetAccessRepoIDs", err)
196200
return
@@ -201,27 +205,30 @@ func Milestones(ctx *context.Context) {
201205
}
202206

203207
var repoIDs []int64
204-
if issueReposQueryPattern.MatchString(reposQuery) {
205-
// remove "[" and "]" from string
206-
reposQuery = reposQuery[1 : len(reposQuery)-1]
207-
//for each ID (delimiter ",") add to int to repoIDs
208-
reposSet := false
209-
for _, rID := range strings.Split(reposQuery, ",") {
210-
// Ensure nonempty string entries
211-
if rID != "" && rID != "0" {
212-
reposSet = true
213-
rIDint64, err := strconv.ParseInt(rID, 10, 64)
214-
if err == nil && com.IsSliceContainsInt64(userRepoIDs, rIDint64) {
215-
repoIDs = append(repoIDs, rIDint64)
208+
if len(reposQuery) != 0 {
209+
if issueReposQueryPattern.MatchString(reposQuery) {
210+
// remove "[" and "]" from string
211+
reposQuery = reposQuery[1 : len(reposQuery)-1]
212+
//for each ID (delimiter ",") add to int to repoIDs
213+
reposSet := false
214+
for _, rID := range strings.Split(reposQuery, ",") {
215+
// Ensure nonempty string entries
216+
if rID != "" && rID != "0" {
217+
reposSet = true
218+
rIDint64, err := strconv.ParseInt(rID, 10, 64)
219+
// If the repo id specified by query is not parseable or not accessible by user, just ignore it.
220+
if err == nil && com.IsSliceContainsInt64(userRepoIDs, rIDint64) {
221+
repoIDs = append(repoIDs, rIDint64)
222+
}
216223
}
217224
}
225+
if reposSet && len(repoIDs) == 0 {
226+
// force an empty result
227+
repoIDs = []int64{-1}
228+
}
229+
} else {
230+
log.Warn("issueReposQueryPattern not match with query")
218231
}
219-
if reposSet && len(repoIDs) == 0 {
220-
// force an empty result
221-
repoIDs = []int64{-1}
222-
}
223-
} else {
224-
log.Error("issueReposQueryPattern not match with query")
225232
}
226233

227234
if len(repoIDs) == 0 {
@@ -256,26 +263,6 @@ func Milestones(ctx *context.Context) {
256263
}
257264
}
258265
showReposMap[rID] = repo
259-
260-
// Check if user has access to given repository.
261-
perm, err := models.GetUserRepoPermission(repo, ctxUser)
262-
if err != nil {
263-
ctx.ServerError("GetUserRepoPermission", fmt.Errorf("[%d]%v", rID, err))
264-
return
265-
}
266-
267-
if !perm.CanRead(models.UnitTypeIssues) {
268-
if log.IsTrace() {
269-
log.Trace("Permission Denied: User %-v cannot read %-v of repo %-v\n"+
270-
"User in repo has Permissions: %-+v",
271-
ctxUser,
272-
models.UnitTypeIssues,
273-
repo,
274-
perm)
275-
}
276-
ctx.Status(404)
277-
return
278-
}
279266
}
280267

281268
showRepos := models.RepositoryListOfMap(showReposMap)
@@ -345,9 +332,11 @@ var issueReposQueryPattern = regexp.MustCompile(`^\[\d+(,\d+)*,?\]$`)
345332
// Issues render the user issues page
346333
func Issues(ctx *context.Context) {
347334
isPullList := ctx.Params(":type") == "pulls"
335+
unitType := models.UnitTypeIssues
348336
if isPullList {
349337
ctx.Data["Title"] = ctx.Tr("pull_requests")
350338
ctx.Data["PageIsPulls"] = true
339+
unitType = models.UnitTypePullRequests
351340
} else {
352341
ctx.Data["Title"] = ctx.Tr("issues")
353342
ctx.Data["PageIsIssues"] = true
@@ -404,7 +393,7 @@ func Issues(ctx *context.Context) {
404393
}
405394
}
406395
} else {
407-
log.Error("issueReposQueryPattern not match with query")
396+
log.Warn("issueReposQueryPattern not match with query")
408397
}
409398
}
410399

@@ -424,11 +413,12 @@ func Issues(ctx *context.Context) {
424413
ctx.ServerError("env.RepoIDs", err)
425414
return
426415
}
427-
} else {
428-
unitType := models.UnitTypeIssues
429-
if isPullList {
430-
unitType = models.UnitTypePullRequests
416+
userRepoIDs, err = models.FilterOutRepoIdsWithoutUnitAccess(ctx.User, userRepoIDs, unitType)
417+
if err != nil {
418+
ctx.ServerError("FilterOutRepoIdsWithoutUnitAccess", err)
419+
return
431420
}
421+
} else {
432422
userRepoIDs, err = ctxUser.GetAccessRepoIDs(unitType)
433423
if err != nil {
434424
ctx.ServerError("ctxUser.GetAccessRepoIDs", err)

0 commit comments

Comments
 (0)