Skip to content

Commit ecdb4c1

Browse files
guillep2klafriks
authored andcommitted
Fix permission checks for close/reopen from commit (#8875) (#9033)
* Fix checks for close/reopen from commit * Fix permission order
1 parent a0e76de commit ecdb4c1

File tree

2 files changed

+31
-18
lines changed

2 files changed

+31
-18
lines changed

models/action.go

+29-16
Original file line numberDiff line numberDiff line change
@@ -533,32 +533,45 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
533533
}
534534
refMarked[key] = true
535535

536-
// only create comments for issues if user has permission for it
537-
if perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(UnitTypeIssues) {
538-
message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, repo.Link(), c.Sha1, html.EscapeString(c.Message))
539-
if err = CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil {
540-
return err
541-
}
536+
// FIXME: this kind of condition is all over the code, it should be consolidated in a single place
537+
canclose := perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(UnitTypeIssues) || refIssue.PosterID == doer.ID
538+
cancomment := canclose || perm.CanRead(UnitTypeIssues)
539+
540+
// Don't proceed if the user can't comment
541+
if !cancomment {
542+
continue
542543
}
543544

544-
// Process closing/reopening keywords
545-
if ref.Action != references.XRefActionCloses && ref.Action != references.XRefActionReopens {
545+
message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, repo.Link(), c.Sha1, html.EscapeString(c.Message))
546+
if err = CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil {
547+
return err
548+
}
549+
550+
// Only issues can be closed/reopened this way, and user needs the correct permissions
551+
if refIssue.IsPull || !canclose {
546552
continue
547553
}
548554

549-
// Change issue status only if the commit has been pushed to the default branch.
550-
// and if the repo is configured to allow only that
551-
// FIXME: we should be using Issue.ref if set instead of repo.DefaultBranch
552-
if repo.DefaultBranch != branchName && !repo.CloseIssuesViaCommitInAnyBranch {
555+
// Only process closing/reopening keywords
556+
if ref.Action != references.XRefActionCloses && ref.Action != references.XRefActionReopens {
553557
continue
554558
}
555559

556-
// only close issues in another repo if user has push access
557-
if perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(UnitTypeCode) {
558-
if err := changeIssueStatus(refRepo, refIssue, doer, ref.Action == references.XRefActionCloses); err != nil {
559-
return err
560+
if !repo.CloseIssuesViaCommitInAnyBranch {
561+
// If the issue was specified to be in a particular branch, don't allow commits in other branches to close it
562+
if refIssue.Ref != "" {
563+
if branchName != refIssue.Ref {
564+
continue
565+
}
566+
// Otherwise, only process commits to the default branch
567+
} else if branchName != repo.DefaultBranch {
568+
continue
560569
}
561570
}
571+
572+
if err := changeIssueStatus(refRepo, refIssue, doer, ref.Action == references.XRefActionCloses); err != nil {
573+
return err
574+
}
562575
}
563576
}
564577
return nil

models/action_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
219219
PosterID: user.ID,
220220
IssueID: 1,
221221
}
222-
issueBean := &Issue{RepoID: repo.ID, Index: 2}
222+
issueBean := &Issue{RepoID: repo.ID, Index: 4}
223223

224224
AssertNotExistsBean(t, commentBean)
225225
AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
@@ -273,7 +273,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
273273
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
274274
repo.Owner = user
275275

276-
issueBean := &Issue{RepoID: repo.ID, Index: 2}
276+
issueBean := &Issue{RepoID: repo.ID, Index: 4}
277277

278278
AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
279279
assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))

0 commit comments

Comments
 (0)