Improve issue comment management (#2588)

This commit is contained in:
onukura
2020-12-07 04:19:30 +09:00
committed by GitHub
parent 1b32e13113
commit 04c8f8b864
7 changed files with 53 additions and 5 deletions

View File

@@ -112,6 +112,7 @@ trait IssuesControllerBase extends ControllerBase {
getLabels(owner, name), getLabels(owner, name),
isIssueEditable(repository), isIssueEditable(repository),
isIssueManageable(repository), isIssueManageable(repository),
isIssueCommentManageable(repository),
repository repository
) )
} }
@@ -238,8 +239,8 @@ trait IssuesControllerBase extends ControllerBase {
defining(repository.owner, repository.name) { defining(repository.owner, repository.name) {
case (owner, name) => case (owner, name) =>
getComment(owner, name, params("id")).map { comment => getComment(owner, name, params("id")).map { comment =>
if (isEditableContent(owner, name, comment.commentedUserName)) { if (isDeletableComment(owner, name, comment.commentedUserName)) {
Ok(deleteComment(comment.issueId, comment.commentId)) Ok(deleteComment(repository.owner, repository.name, comment.issueId, comment.commentId))
} else Unauthorized() } else Unauthorized()
} getOrElse NotFound() } getOrElse NotFound()
} }
@@ -496,4 +497,13 @@ trait IssuesControllerBase extends ControllerBase {
): Boolean = { ): Boolean = {
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName 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
}
} }

View File

@@ -142,7 +142,7 @@ trait HandleCommentService {
): Option[IssueComment] = context.loginAccount.flatMap { _ => ): Option[IssueComment] = context.loginAccount.flatMap { _ =>
comment.action match { comment.action match {
case "comment" => case "comment" =>
val deleteResult = deleteComment(comment.issueId, comment.commentId) val deleteResult = deleteComment(repoInfo.owner, repoInfo.name, comment.issueId, comment.commentId)
val registry = PluginRegistry() val registry = PluginRegistry()
val hooks: Seq[IssueHook] = if (issue.isPullRequest) registry.getPullRequestHooks else registry.getIssueHooks val hooks: Seq[IssueHook] = if (issue.isPullRequest) registry.getPullRequestHooks else registry.getIssueHooks
hooks.foreach(_.deletedComment(comment.commentId, issue, repoInfo)) hooks.foreach(_.deletedComment(comment.commentId, issue, repoInfo))

View File

@@ -74,6 +74,13 @@ trait IssueCreationService {
hasDeveloperRole(repository.owner, repository.name, context.loginAccount) hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
} }
/**
* 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. * Tests whether an logged-in user can post issues.
*/ */

View File

@@ -660,7 +660,10 @@ trait IssuesService {
IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.updatedDate)).update(content, currentDate) 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) Issues.filter(_.issueId === issueId.bind).map(_.updatedDate).update(currentDate)
IssueComments.filter(_.byPrimaryKey(commentId)).firstOption match { IssueComments.filter(_.byPrimaryKey(commentId)).firstOption match {
case Some(c) if c.action == "reopen_comment" => case Some(c) if c.action == "reopen_comment" =>
@@ -669,6 +672,16 @@ trait IssuesService {
IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.action)).update("Close", "close") IssueComments.filter(_.byPrimaryKey(commentId)).map(t => (t.content, t.action)).update("Close", "close")
case Some(_) => case Some(_) =>
IssueComments.filter(_.byPrimaryKey(commentId)).delete 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
)
} }
} }

View File

@@ -254,6 +254,17 @@
</div> </div>
</div> </div>
} }
case "delete_comment" => {
<div class="discussion-item discussion-item-delete-comment">
<div class="discussion-item-header">
<span class="discussion-item-icon"><i class="octicon octicon-trashcan"></i></span>
@helpers.avatar(comment.commentedUserName, 16)
@helpers.user(comment.commentedUserName, styleClass="username strong")
deleted the comment
@gitbucket.core.helper.html.datetimeago(comment.registeredDate)
</div>
</div>
}
case _ => { case _ => {
@showFormattedComment(comment) @showFormattedComment(comment)
} }

View File

@@ -7,6 +7,7 @@
labels: List[gitbucket.core.model.Label], labels: List[gitbucket.core.model.Label],
isEditable: Boolean, isEditable: Boolean,
isManageable: Boolean, isManageable: Boolean,
isCommentManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context) repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers @import gitbucket.core.view.helpers
@gitbucket.core.html.main(s"${issue.title} - Issue #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)){ @gitbucket.core.html.main(s"${issue.title} - Issue #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)){
@@ -51,7 +52,7 @@
<hr> <hr>
<div style="margin-top: 15px;"> <div style="margin-top: 15px;">
<div class="col-md-9"> <div class="col-md-9">
@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) @gitbucket.core.issues.html.commentform(issue, true, isEditable, isManageable, repository)
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

View File

@@ -950,6 +950,12 @@ pre.reset.discussion-item-content-text{
color: white; color: white;
} }
.discussion-item-delete-comment .discussion-item-icon {
background-color: #767676;
padding-top: 1px;
color: white;
}
.priority-sort-handle { .priority-sort-handle {
margin-top: 3px; margin-top: 3px;
padding-right: 10px; padding-right: 10px;