Fix issue dependencies (#27736) (#28776)

Backport #27736 by @lng2020

Fix #27722
Fix #27357
Fix #25837
Fix #28732
1. Fix the typo `BlockingByDependenciesNotPermitted`, which causes the
`not permitted message` not to show. The correct one is `Blocking` or
`BlockedBy`
2. Rewrite the perm check. The perm check uses a very tricky way to
avoid duplicate checks for a slice of issues, which is confusing. In
fact, it's also the reason causing the bug. It uses `lastRepoID` and
`lastPerm` to avoid duplicate checks, but forgets to assign the
`lastPerm` at the end of the code block. So I rewrote this to avoid this
trick.
![I U1AT{GNFY3
1HZ`6L{(2L](https://github.com/go-gitea/gitea/assets/70063547/79acd02a-a567-4316-ae0d-11c6461becf1)
3. It also reuses the `blocks` slice, which is even more confusing. So I
rewrote this too.

![UARFPXRGGZQFB7J$2`R}5_R](https://github.com/go-gitea/gitea/assets/70063547/f21cff0f-d9ac-4ce4-ae4d-adffc98ecd99)

Co-authored-by: Nanguan Lin <70063547+lng2020@users.noreply.github.com>
(cherry picked from commit 571822b6eca07832f6b5ff633bec8ab8fdb32624)
This commit is contained in:
Giteabot 2024-01-13 05:29:22 +08:00 committed by Earl Warren
parent 1069987293
commit 2ab54a9c06
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
2 changed files with 55 additions and 56 deletions

View file

@ -102,14 +102,16 @@ func GetIssueDependencies(ctx *context.APIContext) {
return return
} }
var lastRepoID int64 repoPerms := make(map[int64]access_model.Permission)
var lastPerm access_model.Permission repoPerms[ctx.Repo.Repository.ID] = ctx.Repo.Permission
for _, blocker := range blockersInfo { for _, blocker := range blockersInfo {
// Get the permissions for this repository // Get the permissions for this repository
perm := lastPerm // If the repo ID exists in the map, return the exist permissions
if lastRepoID != blocker.Repository.ID { // else get the permission and add it to the map
if blocker.Repository.ID == ctx.Repo.Repository.ID { var perm access_model.Permission
perm = ctx.Repo.Permission existPerm, ok := repoPerms[blocker.RepoID]
if ok {
perm = existPerm
} else { } else {
var err error var err error
perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer) perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer)
@ -117,8 +119,7 @@ func GetIssueDependencies(ctx *context.APIContext) {
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return return
} }
} repoPerms[blocker.RepoID] = perm
lastRepoID = blocker.Repository.ID
} }
// check permission // check permission
@ -341,20 +342,23 @@ func GetIssueBlocks(ctx *context.APIContext) {
return return
} }
var lastRepoID int64
var lastPerm access_model.Permission
var issues []*issues_model.Issue var issues []*issues_model.Issue
repoPerms := make(map[int64]access_model.Permission)
repoPerms[ctx.Repo.Repository.ID] = ctx.Repo.Permission
for i, depMeta := range deps { for i, depMeta := range deps {
if i < skip || i >= max { if i < skip || i >= max {
continue continue
} }
// Get the permissions for this repository // Get the permissions for this repository
perm := lastPerm // If the repo ID exists in the map, return the exist permissions
if lastRepoID != depMeta.Repository.ID { // else get the permission and add it to the map
if depMeta.Repository.ID == ctx.Repo.Repository.ID { var perm access_model.Permission
perm = ctx.Repo.Permission existPerm, ok := repoPerms[depMeta.RepoID]
if ok {
perm = existPerm
} else { } else {
var err error var err error
perm, err = access_model.GetUserRepoPermission(ctx, &depMeta.Repository, ctx.Doer) perm, err = access_model.GetUserRepoPermission(ctx, &depMeta.Repository, ctx.Doer)
@ -362,8 +366,7 @@ func GetIssueBlocks(ctx *context.APIContext) {
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return return
} }
} repoPerms[depMeta.RepoID] = perm
lastRepoID = depMeta.Repository.ID
} }
if !perm.CanReadIssuesOrPulls(depMeta.Issue.IsPull) { if !perm.CanReadIssuesOrPulls(depMeta.Issue.IsPull) {

View file

@ -1951,7 +1951,7 @@ func ViewIssue(ctx *context.Context) {
return return
} }
ctx.Data["BlockingDependencies"], ctx.Data["BlockingByDependenciesNotPermitted"] = checkBlockedByIssues(ctx, blocking) ctx.Data["BlockingDependencies"], ctx.Data["BlockingDependenciesNotPermitted"] = checkBlockedByIssues(ctx, blocking)
if ctx.Written() { if ctx.Written() {
return return
} }
@ -2012,16 +2012,16 @@ func ViewIssue(ctx *context.Context) {
// checkBlockedByIssues return canRead and notPermitted // checkBlockedByIssues return canRead and notPermitted
func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.DependencyInfo) (canRead, notPermitted []*issues_model.DependencyInfo) { func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.DependencyInfo) (canRead, notPermitted []*issues_model.DependencyInfo) {
var ( repoPerms := make(map[int64]access_model.Permission)
lastRepoID int64 repoPerms[ctx.Repo.Repository.ID] = ctx.Repo.Permission
lastPerm access_model.Permission for _, blocker := range blockers {
)
for i, blocker := range blockers {
// Get the permissions for this repository // Get the permissions for this repository
perm := lastPerm // If the repo ID exists in the map, return the exist permissions
if lastRepoID != blocker.Repository.ID { // else get the permission and add it to the map
if blocker.Repository.ID == ctx.Repo.Repository.ID { var perm access_model.Permission
perm = ctx.Repo.Permission existPerm, ok := repoPerms[blocker.RepoID]
if ok {
perm = existPerm
} else { } else {
var err error var err error
perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer) perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer)
@ -2029,21 +2029,17 @@ func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.Depende
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return nil, nil return nil, nil
} }
repoPerms[blocker.RepoID] = perm
} }
lastRepoID = blocker.Repository.ID if perm.CanReadIssuesOrPulls(blocker.Issue.IsPull) {
} canRead = append(canRead, blocker)
} else {
// check permission notPermitted = append(notPermitted, blocker)
if !perm.CanReadIssuesOrPulls(blocker.Issue.IsPull) {
blockers[len(notPermitted)], blockers[i] = blocker, blockers[len(notPermitted)]
notPermitted = blockers[:len(notPermitted)+1]
} }
} }
blockers = blockers[len(notPermitted):] sortDependencyInfo(canRead)
sortDependencyInfo(blockers)
sortDependencyInfo(notPermitted) sortDependencyInfo(notPermitted)
return canRead, notPermitted
return blockers, notPermitted
} }
func sortDependencyInfo(blockers []*issues_model.DependencyInfo) { func sortDependencyInfo(blockers []*issues_model.DependencyInfo) {