summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorLanre Adelowo <adelowomailbox@gmail.com>2019-02-18 21:55:04 +0100
committerLauris BH <lauris@nix.lv>2019-02-18 22:55:04 +0200
commit44114b38e601c8bf44f575daef1d0e0597f37d1d (patch)
treed2d271b31bff505a09c2faf04d5fea69a9f9d58c /routers
parent64ce159a6eacc81962d07a8f5ef7f69c17365363 (diff)
downloadgitea-44114b38e601c8bf44f575daef1d0e0597f37d1d.tar.gz
gitea-44114b38e601c8bf44f575daef1d0e0597f37d1d.zip
Implement "conversation lock" for issue comments (#5073)
Diffstat (limited to 'routers')
-rw-r--r--routers/api/v1/repo/issue_comment.go6
-rw-r--r--routers/repo/issue.go25
-rw-r--r--routers/repo/issue_lock.go71
-rw-r--r--routers/routes/routes.go11
4 files changed, 112 insertions, 1 deletions
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
index 720513f007..3e6f04eb7a 100644
--- a/routers/api/v1/repo/issue_comment.go
+++ b/routers/api/v1/repo/issue_comment.go
@@ -5,6 +5,7 @@
package repo
import (
+ "errors"
"time"
"code.gitea.io/gitea/models"
@@ -169,6 +170,11 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti
return
}
+ if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin {
+ ctx.Error(403, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked")))
+ return
+ }
+
comment, err := models.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Body, nil)
if err != nil {
ctx.Error(500, "CreateIssueComment", err)
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 9767d11136..6783d279b5 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -57,6 +57,23 @@ var (
}
)
+// MustAllowUserComment checks to make sure if an issue is locked.
+// If locked and user has permissions to write to the repository,
+// then the comment is allowed, else it is blocked
+func MustAllowUserComment(ctx *context.Context) {
+
+ issue := GetActionIssue(ctx)
+ if ctx.Written() {
+ return
+ }
+
+ if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin {
+ ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
+ ctx.Redirect(issue.HTMLURL())
+ return
+ }
+}
+
// MustEnableIssues check if repository enable internal issues
func MustEnableIssues(ctx *context.Context) {
if !ctx.Repo.CanRead(models.UnitTypeIssues) &&
@@ -898,6 +915,9 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + ctx.Data["Link"].(string)
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.User.ID)
ctx.Data["IsIssueWriter"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
+ ctx.Data["IsRepoAdmin"] = ctx.IsSigned && (ctx.Repo.IsAdmin() || ctx.User.IsAdmin)
+ ctx.Data["IsRepoIssuesWriter"] = ctx.IsSigned && (ctx.Repo.CanWrite(models.UnitTypeIssues) || ctx.User.IsAdmin)
+ ctx.Data["LockReasons"] = setting.Repository.Issue.LockReasons
ctx.HTML(200, tplIssueView)
}
@@ -1118,6 +1138,11 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) {
ctx.Error(403)
+ }
+
+ if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin {
+ ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
+ ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
return
}
diff --git a/routers/repo/issue_lock.go b/routers/repo/issue_lock.go
new file mode 100644
index 0000000000..fa87588319
--- /dev/null
+++ b/routers/repo/issue_lock.go
@@ -0,0 +1,71 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package repo
+
+import (
+ "net/http"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/auth"
+ "code.gitea.io/gitea/modules/context"
+)
+
+// LockIssue locks an issue. This would limit commenting abilities to
+// users with write access to the repo.
+func LockIssue(ctx *context.Context, form auth.IssueLockForm) {
+
+ issue := GetActionIssue(ctx)
+ if ctx.Written() {
+ return
+ }
+
+ if issue.IsLocked {
+ ctx.Flash.Error(ctx.Tr("repo.issues.lock_duplicate"))
+ ctx.Redirect(issue.HTMLURL())
+ return
+ }
+
+ if !form.HasValidReason() {
+ ctx.Flash.Error(ctx.Tr("repo.issues.lock.unknown_reason"))
+ ctx.Redirect(issue.HTMLURL())
+ return
+ }
+
+ if err := models.LockIssue(&models.IssueLockOptions{
+ Doer: ctx.User,
+ Issue: issue,
+ Reason: form.Reason,
+ }); err != nil {
+ ctx.ServerError("LockIssue", err)
+ return
+ }
+
+ ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
+}
+
+// UnlockIssue unlocks a previously locked issue.
+func UnlockIssue(ctx *context.Context) {
+
+ issue := GetActionIssue(ctx)
+ if ctx.Written() {
+ return
+ }
+
+ if !issue.IsLocked {
+ ctx.Flash.Error(ctx.Tr("repo.issues.unlock_error"))
+ ctx.Redirect(issue.HTMLURL())
+ return
+ }
+
+ if err := models.UnlockIssue(&models.IssueLockOptions{
+ Doer: ctx.User,
+ Issue: issue,
+ }); err != nil {
+ ctx.ServerError("UnlockIssue", err)
+ return
+ }
+
+ ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
+}
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 8ab7ff9bea..b73b030a51 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -432,6 +432,13 @@ func RegisterRoutes(m *macaron.Macaron) {
reqRepoIssuesOrPullsWriter := context.RequireRepoWriterOr(models.UnitTypeIssues, models.UnitTypePullRequests)
reqRepoIssuesOrPullsReader := context.RequireRepoReaderOr(models.UnitTypeIssues, models.UnitTypePullRequests)
+ reqRepoIssueWriter := func(ctx *context.Context) {
+ if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
+ ctx.Error(403)
+ return
+ }
+ }
+
// ***** START: Organization *****
m.Group("/org", func() {
m.Group("", func() {
@@ -574,7 +581,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/add", repo.AddDependency)
m.Post("/delete", repo.RemoveDependency)
})
- m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
+ m.Combo("/comments").Post(repo.MustAllowUserComment, bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
m.Group("/times", func() {
m.Post("/add", bindIgnErr(auth.AddTimeManuallyForm{}), repo.AddTimeManually)
m.Group("/stopwatch", func() {
@@ -583,6 +590,8 @@ func RegisterRoutes(m *macaron.Macaron) {
})
})
m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction)
+ m.Post("/lock", reqRepoIssueWriter, bindIgnErr(auth.IssueLockForm{}), repo.LockIssue)
+ m.Post("/unlock", reqRepoIssueWriter, repo.UnlockIssue)
}, context.RepoMustNotBeArchived())
m.Post("/labels", reqRepoIssuesOrPullsWriter, repo.UpdateIssueLabel)