diff --git a/src/main/scala/gitbucket/core/controller/IssuesController.scala b/src/main/scala/gitbucket/core/controller/IssuesController.scala index 4f68c6d..a0b711f 100644 --- a/src/main/scala/gitbucket/core/controller/IssuesController.scala +++ b/src/main/scala/gitbucket/core/controller/IssuesController.scala @@ -112,6 +112,7 @@ getLabels(owner, name), isIssueEditable(repository), isIssueManageable(repository), + isIssueCommentManageable(repository), repository ) } @@ -238,8 +239,8 @@ defining(repository.owner, repository.name) { case (owner, name) => getComment(owner, name, params("id")).map { comment => - if (isEditableContent(owner, name, comment.commentedUserName)) { - Ok(deleteComment(comment.issueId, comment.commentId)) + if (isDeletableComment(owner, name, comment.commentedUserName)) { + Ok(deleteComment(repository.owner, repository.name, comment.issueId, comment.commentId)) } else Unauthorized() } getOrElse NotFound() } @@ -496,4 +497,13 @@ ): Boolean = { hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName } + + /** + * Tests whether an issue comment is deletable by a logged-in user. + */ + private def isDeletableComment(owner: String, repository: String, author: String)( + implicit context: Context + ): Boolean = { + hasOwnerRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName + } } diff --git a/src/main/scala/gitbucket/core/service/HandleCommentService.scala b/src/main/scala/gitbucket/core/service/HandleCommentService.scala index 512c843..0251c8e 100644 --- a/src/main/scala/gitbucket/core/service/HandleCommentService.scala +++ b/src/main/scala/gitbucket/core/service/HandleCommentService.scala @@ -142,7 +142,7 @@ ): Option[IssueComment] = context.loginAccount.flatMap { _ => comment.action match { case "comment" => - val deleteResult = deleteComment(comment.issueId, comment.commentId) + val deleteResult = deleteComment(repoInfo.owner, repoInfo.name, comment.issueId, comment.commentId) val registry = PluginRegistry() val hooks: Seq[IssueHook] = if (issue.isPullRequest) registry.getPullRequestHooks else registry.getIssueHooks hooks.foreach(_.deletedComment(comment.commentId, issue, repoInfo)) diff --git a/src/main/scala/gitbucket/core/service/IssueCreationService.scala b/src/main/scala/gitbucket/core/service/IssueCreationService.scala index fbd25b5..c56cf0c 100644 --- a/src/main/scala/gitbucket/core/service/IssueCreationService.scala +++ b/src/main/scala/gitbucket/core/service/IssueCreationService.scala @@ -75,6 +75,13 @@ } /** + * Tests whether an logged-in user can manage issues comment. + */ + protected def isIssueCommentManageable(repository: RepositoryInfo)(implicit context: Context, s: Session): Boolean = { + hasOwnerRole(repository.owner, repository.name, context.loginAccount) + } + + /** * Tests whether an logged-in user can post issues. */ protected def isIssueEditable(repository: RepositoryInfo)(implicit context: Context, s: Session): Boolean = { diff --git a/src/main/scala/gitbucket/core/service/IssuesService.scala b/src/main/scala/gitbucket/core/service/IssuesService.scala index 94240ed..b827dc6 100644 --- a/src/main/scala/gitbucket/core/service/IssuesService.scala +++ b/src/main/scala/gitbucket/core/service/IssuesService.scala @@ -660,7 +660,10 @@ IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.updatedDate)).update(content, currentDate) } - def deleteComment(issueId: Int, commentId: Int)(implicit s: Session): Int = { + def deleteComment(owner: String, repository: String, issueId: Int, commentId: Int)( + implicit context: Context, + s: Session + ): Int = { Issues.filter(_.issueId === issueId.bind).map(_.updatedDate).update(currentDate) IssueComments.filter(_.byPrimaryKey(commentId)).firstOption match { case Some(c) if c.action == "reopen_comment" => @@ -669,6 +672,16 @@ IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.action)).update("Close", "close") case Some(_) => IssueComments.filter(_.byPrimaryKey(commentId)).delete + IssueComments insert IssueComment( + userName = owner, + repositoryName = repository, + issueId = issueId, + action = "delete_comment", + commentedUserName = context.loginAccount.map(_.userName).getOrElse("Unknown user"), + content = s"", + registeredDate = currentDate, + updatedDate = currentDate + ) } } diff --git a/src/main/twirl/gitbucket/core/issues/commentlist.scala.html b/src/main/twirl/gitbucket/core/issues/commentlist.scala.html index a0e36a0..75b178f 100644 --- a/src/main/twirl/gitbucket/core/issues/commentlist.scala.html +++ b/src/main/twirl/gitbucket/core/issues/commentlist.scala.html @@ -254,6 +254,17 @@ } + case "delete_comment" => { +
+
+ + @helpers.avatar(comment.commentedUserName, 16) + @helpers.user(comment.commentedUserName, styleClass="username strong") + deleted the comment + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) +
+
+ } case _ => { @showFormattedComment(comment) } diff --git a/src/main/twirl/gitbucket/core/issues/issue.scala.html b/src/main/twirl/gitbucket/core/issues/issue.scala.html index 885a58b..79072b4 100644 --- a/src/main/twirl/gitbucket/core/issues/issue.scala.html +++ b/src/main/twirl/gitbucket/core/issues/issue.scala.html @@ -7,6 +7,7 @@ labels: List[gitbucket.core.model.Label], isEditable: Boolean, isManageable: Boolean, + isCommentManageable: Boolean, repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context) @import gitbucket.core.view.helpers @gitbucket.core.html.main(s"${issue.title} - Issue #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)){ @@ -51,7 +52,7 @@
- @gitbucket.core.issues.html.commentlist(Some(issue), comments, isManageable, repository) + @gitbucket.core.issues.html.commentlist(Some(issue), comments, isCommentManageable, repository) @gitbucket.core.issues.html.commentform(issue, true, isEditable, isManageable, repository)
diff --git a/src/main/webapp/assets/common/css/gitbucket.css b/src/main/webapp/assets/common/css/gitbucket.css index 79986a9..f4420f2 100644 --- a/src/main/webapp/assets/common/css/gitbucket.css +++ b/src/main/webapp/assets/common/css/gitbucket.css @@ -950,6 +950,12 @@ color: white; } +.discussion-item-delete-comment .discussion-item-icon { + background-color: #767676; + padding-top: 1px; + color: white; +} + .priority-sort-handle { margin-top: 3px; padding-right: 10px;