]> source.dussan.org Git - gitea.git/commitdiff
Fix permission checks for close/reopen from commit (#8875) (#9033)
authorguillep2k <18600385+guillep2k@users.noreply.github.com>
Fri, 15 Nov 2019 22:11:40 +0000 (19:11 -0300)
committerLauris BH <lauris@nix.lv>
Fri, 15 Nov 2019 22:11:40 +0000 (00:11 +0200)
* Fix checks for close/reopen from commit

* Fix permission order

models/action.go
models/action_test.go

index 2d2999f8809a42e367de3d64d4a9acaf0906fa2a..626ae1913dfc66632d8a5a79e793b5dacc5174b3 100644 (file)
@@ -533,32 +533,45 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
                        }
                        refMarked[key] = true
 
-                       // only create comments for issues if user has permission for it
-                       if perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(UnitTypeIssues) {
-                               message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, repo.Link(), c.Sha1, html.EscapeString(c.Message))
-                               if err = CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil {
-                                       return err
-                               }
+                       // FIXME: this kind of condition is all over the code, it should be consolidated in a single place
+                       canclose := perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(UnitTypeIssues) || refIssue.PosterID == doer.ID
+                       cancomment := canclose || perm.CanRead(UnitTypeIssues)
+
+                       // Don't proceed if the user can't comment
+                       if !cancomment {
+                               continue
                        }
 
-                       // Process closing/reopening keywords
-                       if ref.Action != references.XRefActionCloses && ref.Action != references.XRefActionReopens {
+                       message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, repo.Link(), c.Sha1, html.EscapeString(c.Message))
+                       if err = CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil {
+                               return err
+                       }
+
+                       // Only issues can be closed/reopened this way, and user needs the correct permissions
+                       if refIssue.IsPull || !canclose {
                                continue
                        }
 
-                       // Change issue status only if the commit has been pushed to the default branch.
-                       // and if the repo is configured to allow only that
-                       // FIXME: we should be using Issue.ref if set instead of repo.DefaultBranch
-                       if repo.DefaultBranch != branchName && !repo.CloseIssuesViaCommitInAnyBranch {
+                       // Only process closing/reopening keywords
+                       if ref.Action != references.XRefActionCloses && ref.Action != references.XRefActionReopens {
                                continue
                        }
 
-                       // only close issues in another repo if user has push access
-                       if perm.IsAdmin() || perm.IsOwner() || perm.CanWrite(UnitTypeCode) {
-                               if err := changeIssueStatus(refRepo, refIssue, doer, ref.Action == references.XRefActionCloses); err != nil {
-                                       return err
+                       if !repo.CloseIssuesViaCommitInAnyBranch {
+                               // If the issue was specified to be in a particular branch, don't allow commits in other branches to close it
+                               if refIssue.Ref != "" {
+                                       if branchName != refIssue.Ref {
+                                               continue
+                                       }
+                                       // Otherwise, only process commits to the default branch
+                               } else if branchName != repo.DefaultBranch {
+                                       continue
                                }
                        }
+
+                       if err := changeIssueStatus(refRepo, refIssue, doer, ref.Action == references.XRefActionCloses); err != nil {
+                               return err
+                       }
                }
        }
        return nil
index df41556850d0ce02b3088115bd645ed2f0249d9a..25922b2247cabc1cebaa31bd01cf4c48141839a2 100644 (file)
@@ -219,7 +219,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
                PosterID:  user.ID,
                IssueID:   1,
        }
-       issueBean := &Issue{RepoID: repo.ID, Index: 2}
+       issueBean := &Issue{RepoID: repo.ID, Index: 4}
 
        AssertNotExistsBean(t, commentBean)
        AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
@@ -273,7 +273,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
        repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
        repo.Owner = user
 
-       issueBean := &Issue{RepoID: repo.ID, Index: 2}
+       issueBean := &Issue{RepoID: repo.ID, Index: 4}
 
        AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
        assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))