diff options
author | Lanre Adelowo <adelowomailbox@gmail.com> | 2019-02-18 21:55:04 +0100 |
---|---|---|
committer | Lauris BH <lauris@nix.lv> | 2019-02-18 22:55:04 +0200 |
commit | 44114b38e601c8bf44f575daef1d0e0597f37d1d (patch) | |
tree | d2d271b31bff505a09c2faf04d5fea69a9f9d58c /routers | |
parent | 64ce159a6eacc81962d07a8f5ef7f69c17365363 (diff) | |
download | gitea-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.go | 6 | ||||
-rw-r--r-- | routers/repo/issue.go | 25 | ||||
-rw-r--r-- | routers/repo/issue_lock.go | 71 | ||||
-rw-r--r-- | routers/routes/routes.go | 11 |
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) |