mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-01 01:48:24 +00:00
Backport #40016 by @basavaraj-sm05 Project board cards list the pull requests that reference their issue, but loaded them without checking the viewer's access. A private pull request mentioning a public issue showed its title, number and state on that issue's board to anyone who can view the board, anonymous visitors included. Repository and organization boards now skip linked pull requests in repositories where the viewer cannot read pull requests, matching how the issue page already hides such references. Co-authored-by: Basavaraj S m <basavaraj@digiscrypt.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
4 files changed
+68
-38
No files matched your search
@@ -365,25 +365,10 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.Data["issuesAttachmentMap"] = issuesAttachmentMap
|
||||
}
|
||||
|
||||
linkedPrsMap := make(map[int64][]*issues_model.Issue)
|
||||
for _, issuesList := range issuesMap {
|
||||
for _, issue := range issuesList {
|
||||
var referencedIDs []int64
|
||||
for _, comment := range issue.Comments {
|
||||
if comment.RefIssueID != 0 && comment.RefIsPull {
|
||||
referencedIDs = append(referencedIDs, comment.RefIssueID)
|
||||
}
|
||||
}
|
||||
|
||||
if len(referencedIDs) > 0 {
|
||||
if linkedPrs, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
|
||||
IssueIDs: referencedIDs,
|
||||
IsPull: optional.Some(true),
|
||||
}); err == nil {
|
||||
linkedPrsMap[issue.ID] = linkedPrs
|
||||
}
|
||||
}
|
||||
}
|
||||
linkedPrsMap, err := project_service.LoadLinkedPullRequests(ctx, issuesMap, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("LoadLinkedPullRequests", err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Add option to filter also by repository specific labels
|
||||
|
||||
@@ -343,25 +343,10 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.Data["issuesAttachmentMap"] = issuesAttachmentMap
|
||||
}
|
||||
|
||||
linkedPrsMap := make(map[int64][]*issues_model.Issue)
|
||||
for _, issuesList := range issuesMap {
|
||||
for _, issue := range issuesList {
|
||||
var referencedIDs []int64
|
||||
for _, comment := range issue.Comments {
|
||||
if comment.RefIssueID != 0 && comment.RefIsPull {
|
||||
referencedIDs = append(referencedIDs, comment.RefIssueID)
|
||||
}
|
||||
}
|
||||
|
||||
if len(referencedIDs) > 0 {
|
||||
if linkedPrs, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
|
||||
IssueIDs: referencedIDs,
|
||||
IsPull: optional.Some(true),
|
||||
}); err == nil {
|
||||
linkedPrsMap[issue.ID] = linkedPrs
|
||||
}
|
||||
}
|
||||
}
|
||||
linkedPrsMap, err := project_service.LoadLinkedPullRequests(ctx, issuesMap, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("LoadLinkedPullRequests", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["LinkedPRs"] = linkedPrsMap
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gitea.dev/models/db"
|
||||
issues_model "gitea.dev/models/issues"
|
||||
access_model "gitea.dev/models/perm/access"
|
||||
project_model "gitea.dev/models/project"
|
||||
user_model "gitea.dev/models/user"
|
||||
"gitea.dev/modules/optional"
|
||||
@@ -208,6 +209,48 @@ func LoadIssuesFromProject(ctx context.Context, project *project_model.Project,
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// LoadLinkedPullRequests returns, per issue, the pull requests referencing it that the doer can read
|
||||
func LoadLinkedPullRequests(ctx context.Context, issuesMap map[int64]issues_model.IssueList, doer *user_model.User) (map[int64][]*issues_model.Issue, error) {
|
||||
linkedPrsMap := make(map[int64][]*issues_model.Issue)
|
||||
canReadPulls := make(map[int64]bool)
|
||||
for _, issuesList := range issuesMap {
|
||||
for _, issue := range issuesList {
|
||||
var referencedIDs []int64
|
||||
for _, comment := range issue.Comments {
|
||||
if comment.RefIssueID != 0 && comment.RefIsPull {
|
||||
referencedIDs = append(referencedIDs, comment.RefIssueID)
|
||||
}
|
||||
}
|
||||
if len(referencedIDs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
linkedPrs, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
|
||||
IssueIDs: referencedIDs,
|
||||
IsPull: optional.Some(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, pr := range linkedPrs {
|
||||
canRead, ok := canReadPulls[pr.RepoID]
|
||||
if !ok {
|
||||
perm, err := access_model.GetDoerRepoPermission(ctx, pr.Repo, doer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
canRead = perm.CanReadIssuesOrPulls(true)
|
||||
canReadPulls[pr.RepoID] = canRead
|
||||
}
|
||||
if canRead {
|
||||
linkedPrsMap[issue.ID] = append(linkedPrsMap[issue.ID], pr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return linkedPrsMap, nil
|
||||
}
|
||||
|
||||
// NumClosedIssues return counter of closed issues assigned to a project
|
||||
func loadNumClosedIssues(ctx context.Context, p *project_model.Project) error {
|
||||
cnt, err := db.GetEngine(ctx).Table("project_issue").
|
||||
|
||||
@@ -379,6 +379,23 @@ func TestOrgProjectFilterByMilestone(t *testing.T) {
|
||||
|
||||
func TestProjects(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
t.Run("PrivateLinkedPullRequest", func(t *testing.T) {
|
||||
require.NoError(t, db.Insert(t.Context(), &issues_model.Comment{
|
||||
Type: issues_model.CommentTypePullRef,
|
||||
PosterID: 2,
|
||||
IssueID: 1,
|
||||
RefRepoID: 3,
|
||||
RefIssueID: 12,
|
||||
RefIsPull: true,
|
||||
}))
|
||||
const linkedPR = `href="/org3/repo3/pulls/2"`
|
||||
|
||||
resp := MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/projects/1"), http.StatusOK)
|
||||
assert.NotContains(t, resp.Body.String(), linkedPR)
|
||||
|
||||
resp = loginUser(t, "user2").MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/projects/1"), http.StatusOK)
|
||||
assert.Contains(t, resp.Body.String(), linkedPR)
|
||||
})
|
||||
t.Run("LoadIssuesAssigneesForProject", func(t *testing.T) {
|
||||
_ = db.TruncateBeans(t.Context(), "project_issue", "issue_assignees")
|
||||
_ = db.Insert(t.Context(),
|
||||
|
||||
Reference in new issue
Block a user