(refs #1286) Update controllers

This commit is contained in:
Naoki Takezoe
2016-11-04 13:57:39 +09:00
parent 2dfa7a1190
commit 132bb6bee4
17 changed files with 230 additions and 183 deletions

View File

@@ -2,13 +2,13 @@ package gitbucket.core.controller
import gitbucket.core.issues.html
import gitbucket.core.service.IssuesService._
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.service._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Implicits._
import gitbucket.core.util._
import gitbucket.core.view
import gitbucket.core.view.Markdown
import io.github.gitbucket.scalatra.forms._
import org.scalatra.Ok
@@ -70,7 +70,8 @@ trait IssuesControllerBase extends ControllerBase {
getAssignableUserNames(owner, name),
getMilestonesWithIssueCount(owner, name),
getLabels(owner, name),
hasWritePermission(owner, name, context.loginAccount),
isEditable(repository),
isManageable(repository),
repository)
} getOrElse NotFound()
}
@@ -89,50 +90,53 @@ trait IssuesControllerBase extends ControllerBase {
post("/:owner/:repository/issues/new", issueCreateForm)(readableUsersOnly { (form, repository) =>
defining(repository.owner, repository.name){ case (owner, name) =>
val writable = hasWritePermission(owner, name, context.loginAccount)
val userName = context.loginAccount.get.userName
val manageable = isManageable(repository)
val editable = isEditable(repository)
if(editable) {
val userName = context.loginAccount.get.userName
// insert issue
val issueId = createIssue(owner, name, userName, form.title, form.content,
if(writable) form.assignedUserName else None,
if(writable) form.milestoneId else None)
// insert issue
val issueId = createIssue(owner, name, userName, form.title, form.content,
if (manageable) form.assignedUserName else None,
if (manageable) form.milestoneId else None)
// insert labels
if(writable){
form.labelNames.map { value =>
val labels = getLabels(owner, name)
value.split(",").foreach { labelName =>
labels.find(_.labelName == labelName).map { label =>
registerIssueLabel(owner, name, issueId, label.labelId)
// insert labels
if (manageable) {
form.labelNames.map { value =>
val labels = getLabels(owner, name)
value.split(",").foreach { labelName =>
labels.find(_.labelName == labelName).map { label =>
registerIssueLabel(owner, name, issueId, label.labelId)
}
}
}
}
}
// record activity
recordCreateIssueActivity(owner, name, userName, issueId, form.title)
// record activity
recordCreateIssueActivity(owner, name, userName, issueId, form.title)
getIssue(owner, name, issueId.toString).foreach { issue =>
// extract references and create refer comment
createReferComment(owner, name, issue, form.title + " " + form.content.getOrElse(""), context.loginAccount.get)
getIssue(owner, name, issueId.toString).foreach { issue =>
// extract references and create refer comment
createReferComment(owner, name, issue, form.title + " " + form.content.getOrElse(""), context.loginAccount.get)
// call web hooks
callIssuesWebHook("opened", repository, issue, context.baseUrl, context.loginAccount.get)
// call web hooks
callIssuesWebHook("opened", repository, issue, context.baseUrl, context.loginAccount.get)
// notifications
Notifier().toNotify(repository, issue, form.content.getOrElse("")){
Notifier.msgIssue(s"${context.baseUrl}/${owner}/${name}/issues/${issueId}")
// notifications
Notifier().toNotify(repository, issue, form.content.getOrElse("")) {
Notifier.msgIssue(s"${context.baseUrl}/${owner}/${name}/issues/${issueId}")
}
}
}
redirect(s"/${owner}/${name}/issues/${issueId}")
redirect(s"/${owner}/${name}/issues/${issueId}")
} else Unauthorized()
}
})
ajaxPost("/:owner/:repository/issues/edit_title/:id", issueTitleEditForm)(readableUsersOnly { (title, repository) =>
defining(repository.owner, repository.name){ case (owner, name) =>
getIssue(owner, name, params("id")).map { issue =>
if(isEditable(owner, name, issue.openedUserName)){
if(isEditableContent(owner, name, issue.openedUserName)){
// update issue
updateIssue(owner, name, issue.issueId, title, issue.content)
// extract references and create refer comment
@@ -147,7 +151,7 @@ trait IssuesControllerBase extends ControllerBase {
ajaxPost("/:owner/:repository/issues/edit/:id", issueEditForm)(readableUsersOnly { (content, repository) =>
defining(repository.owner, repository.name){ case (owner, name) =>
getIssue(owner, name, params("id")).map { issue =>
if(isEditable(owner, name, issue.openedUserName)){
if(isEditableContent(owner, name, issue.openedUserName)){
// update issue
updateIssue(owner, name, issue.issueId, issue.title, content)
// extract references and create refer comment
@@ -161,7 +165,7 @@ trait IssuesControllerBase extends ControllerBase {
post("/:owner/:repository/issue_comments/new", commentForm)(readableUsersOnly { (form, repository) =>
getIssue(repository.owner, repository.name, form.issueId.toString).flatMap { issue =>
val actionOpt = params.get("action").filter(_ => isEditable(issue.userName, issue.repositoryName, issue.openedUserName))
val actionOpt = params.get("action").filter(_ => isEditableContent(issue.userName, issue.repositoryName, issue.openedUserName))
handleComment(issue, Some(form.content), repository, actionOpt) map { case (issue, id) =>
redirect(s"/${repository.owner}/${repository.name}/${
if(issue.isPullRequest) "pull" else "issues"}/${form.issueId}#comment-${id}")
@@ -171,7 +175,7 @@ trait IssuesControllerBase extends ControllerBase {
post("/:owner/:repository/issue_comments/state", issueStateForm)(readableUsersOnly { (form, repository) =>
getIssue(repository.owner, repository.name, form.issueId.toString).flatMap { issue =>
val actionOpt = params.get("action").filter(_ => isEditable(issue.userName, issue.repositoryName, issue.openedUserName))
val actionOpt = params.get("action").filter(_ => isEditableContent(issue.userName, issue.repositoryName, issue.openedUserName))
handleComment(issue, form.content, repository, actionOpt) map { case (issue, id) =>
redirect(s"/${repository.owner}/${repository.name}/${
if(issue.isPullRequest) "pull" else "issues"}/${form.issueId}#comment-${id}")
@@ -182,7 +186,7 @@ trait IssuesControllerBase extends ControllerBase {
ajaxPost("/:owner/:repository/issue_comments/edit/:id", commentForm)(readableUsersOnly { (form, repository) =>
defining(repository.owner, repository.name){ case (owner, name) =>
getComment(owner, name, params("id")).map { comment =>
if(isEditable(owner, name, comment.commentedUserName)){
if(isEditableContent(owner, name, comment.commentedUserName)){
updateComment(comment.commentId, form.content)
redirect(s"/${owner}/${name}/issue_comments/_data/${comment.commentId}")
} else Unauthorized()
@@ -193,7 +197,7 @@ trait IssuesControllerBase extends ControllerBase {
ajaxPost("/:owner/:repository/issue_comments/delete/:id")(readableUsersOnly { repository =>
defining(repository.owner, repository.name){ case (owner, name) =>
getComment(owner, name, params("id")).map { comment =>
if(isEditable(owner, name, comment.commentedUserName)){
if(isEditableContent(owner, name, comment.commentedUserName)){
Ok(deleteComment(comment.commentId))
} else Unauthorized()
} getOrElse NotFound()
@@ -202,7 +206,7 @@ trait IssuesControllerBase extends ControllerBase {
ajaxGet("/:owner/:repository/issues/_data/:id")(readableUsersOnly { repository =>
getIssue(repository.owner, repository.name, params("id")) map { x =>
if(isEditable(x.userName, x.repositoryName, x.openedUserName)){
if(isEditableContent(x.userName, x.repositoryName, x.openedUserName)){
params.get("dataType") collect {
case t if t == "html" => html.editissue(x.content, x.issueId, repository)
} getOrElse {
@@ -218,7 +222,7 @@ trait IssuesControllerBase extends ControllerBase {
enableAnchor = true,
enableLineBreaks = true,
enableTaskList = true,
hasWritePermission = isEditable(x.userName, x.repositoryName, x.openedUserName)
hasWritePermission = true
)
)
)
@@ -229,7 +233,7 @@ trait IssuesControllerBase extends ControllerBase {
ajaxGet("/:owner/:repository/issue_comments/_data/:id")(readableUsersOnly { repository =>
getComment(repository.owner, repository.name, params("id")) map { x =>
if(isEditable(x.userName, x.repositoryName, x.commentedUserName)){
if(isEditableContent(x.userName, x.repositoryName, x.commentedUserName)){
params.get("dataType") collect {
case t if t == "html" => html.editcomment(x.content, x.commentId, repository)
} getOrElse {
@@ -244,7 +248,7 @@ trait IssuesControllerBase extends ControllerBase {
enableAnchor = true,
enableLineBreaks = true,
enableTaskList = true,
hasWritePermission = isEditable(x.userName, x.repositoryName, x.commentedUserName)
hasWritePermission = true
)
)
)
@@ -346,9 +350,6 @@ trait IssuesControllerBase extends ControllerBase {
val assignedUserName = (key: String) => params.get(key) filter (_.trim != "")
val milestoneId: String => Option[Int] = (key: String) => params.get(key).flatMap(_.toIntOpt)
private def isEditable(owner: String, repository: String, author: String)(implicit context: Context): Boolean =
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
private def executeBatch(repository: RepositoryService.RepositoryInfo)(execute: Int => Unit) = {
params("checked").split(',') map(_.toInt) foreach execute
params("from") match {
@@ -359,8 +360,7 @@ trait IssuesControllerBase extends ControllerBase {
private def searchIssues(repository: RepositoryService.RepositoryInfo) = {
defining(repository.owner, repository.name){ case (owner, repoName) =>
val page = IssueSearchCondition.page(request)
val sessionKey = Keys.Session.Issues(owner, repoName)
val page = IssueSearchCondition.page(request)
// retrieve search condition
val condition = IssueSearchCondition(request)
@@ -376,8 +376,34 @@ trait IssuesControllerBase extends ControllerBase {
countIssue(condition.copy(state = "closed"), false, owner -> repoName),
condition,
repository,
hasWritePermission(owner, repoName, context.loginAccount))
isEditable(repository),
isManageable(repository))
}
}
/**
* Tests whether an logged-in user can manage issues.
*/
private def isManageable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
hasWritePermission(repository.owner, repository.name, context.loginAccount)
}
/**
* Tests whether an logged-in user can post issues.
*/
private def isEditable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
repository.repository.options.issuesOption match {
case "PUBLIC" => hasReadPermission(repository.owner, repository.name, context.loginAccount)
case "PRIVATE" => hasWritePermission(repository.owner, repository.name, context.loginAccount)
case "DISABLE" => false
}
}
/**
* Tests whether an issue or a comment is editable by a logged-in user.
*/
private def isEditableContent(owner: String, repository: String, author: String)(implicit context: Context): Boolean = {
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
}
}

View File

@@ -6,6 +6,7 @@ import gitbucket.core.service.CommitStatusService
import gitbucket.core.service.MergeService
import gitbucket.core.service.IssuesService._
import gitbucket.core.service.PullRequestService._
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.service._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
@@ -14,7 +15,6 @@ import gitbucket.core.util.JGitUtil._
import gitbucket.core.util._
import gitbucket.core.view
import gitbucket.core.view.helpers
import io.github.gitbucket.scalatra.forms._
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.PersonIdent
@@ -24,13 +24,15 @@ import scala.collection.JavaConverters._
class PullRequestsController extends PullRequestsControllerBase
with RepositoryService with AccountService with IssuesService with PullRequestService with MilestonesService with LabelsService
with CommitsService with ActivityService with WebHookPullRequestService with ReferrerAuthenticator with CollaboratorsAuthenticator
with CommitsService with ActivityService with WebHookPullRequestService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator
with CommitStatusService with MergeService with ProtectedBranchService
trait PullRequestsControllerBase extends ControllerBase {
self: RepositoryService with AccountService with IssuesService with MilestonesService with LabelsService
with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService with ReferrerAuthenticator with CollaboratorsAuthenticator
with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator
with CommitStatusService with MergeService with ProtectedBranchService =>
val pullRequestForm = mapping(
@@ -96,7 +98,8 @@ trait PullRequestsControllerBase extends ControllerBase {
getLabels(owner, name),
commits,
diffs,
hasWritePermission(owner, name, context.loginAccount),
isEditable(repository),
isManageable(repository),
repository,
flash.toMap.map(f => f._1 -> f._2.toString))
}
@@ -416,64 +419,68 @@ trait PullRequestsControllerBase extends ControllerBase {
}) getOrElse NotFound()
})
post("/:owner/:repository/pulls/new", pullRequestForm)(referrersOnly { (form, repository) =>
post("/:owner/:repository/pulls/new", pullRequestForm)(readableUsersOnly { (form, repository) =>
defining(repository.owner, repository.name){ case (owner, name) =>
val writable = hasWritePermission(owner, name, context.loginAccount)
val loginUserName = context.loginAccount.get.userName
val manageable = isManageable(repository)
val editable = isEditable(repository)
val issueId = createIssue(
owner = repository.owner,
repository = repository.name,
loginUser = loginUserName,
title = form.title,
content = form.content,
assignedUserName = if(writable) form.assignedUserName else None,
milestoneId = if(writable) form.milestoneId else None,
isPullRequest = true)
if(editable) {
val loginUserName = context.loginAccount.get.userName
createPullRequest(
originUserName = repository.owner,
originRepositoryName = repository.name,
issueId = issueId,
originBranch = form.targetBranch,
requestUserName = form.requestUserName,
requestRepositoryName = form.requestRepositoryName,
requestBranch = form.requestBranch,
commitIdFrom = form.commitIdFrom,
commitIdTo = form.commitIdTo)
val issueId = createIssue(
owner = repository.owner,
repository = repository.name,
loginUser = loginUserName,
title = form.title,
content = form.content,
assignedUserName = if (manageable) form.assignedUserName else None,
milestoneId = if (manageable) form.milestoneId else None,
isPullRequest = true)
// insert labels
if(writable){
form.labelNames.map { value =>
val labels = getLabels(owner, name)
value.split(",").foreach { labelName =>
labels.find(_.labelName == labelName).map { label =>
registerIssueLabel(repository.owner, repository.name, issueId, label.labelId)
createPullRequest(
originUserName = repository.owner,
originRepositoryName = repository.name,
issueId = issueId,
originBranch = form.targetBranch,
requestUserName = form.requestUserName,
requestRepositoryName = form.requestRepositoryName,
requestBranch = form.requestBranch,
commitIdFrom = form.commitIdFrom,
commitIdTo = form.commitIdTo)
// insert labels
if (manageable) {
form.labelNames.map { value =>
val labels = getLabels(owner, name)
value.split(",").foreach { labelName =>
labels.find(_.labelName == labelName).map { label =>
registerIssueLabel(repository.owner, repository.name, issueId, label.labelId)
}
}
}
}
}
// fetch requested branch
fetchAsPullRequest(owner, name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)
// fetch requested branch
fetchAsPullRequest(owner, name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)
// record activity
recordPullRequestActivity(owner, name, loginUserName, issueId, form.title)
// record activity
recordPullRequestActivity(owner, name, loginUserName, issueId, form.title)
// call web hook
callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)
// call web hook
callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)
getIssue(owner, name, issueId.toString) foreach { issue =>
// extract references and create refer comment
createReferComment(owner, name, issue, form.title + " " + form.content.getOrElse(""), context.loginAccount.get)
getIssue(owner, name, issueId.toString) foreach { issue =>
// extract references and create refer comment
createReferComment(owner, name, issue, form.title + " " + form.content.getOrElse(""), context.loginAccount.get)
// notifications
Notifier().toNotify(repository, issue, form.content.getOrElse("")){
Notifier.msgPullRequest(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}")
// notifications
Notifier().toNotify(repository, issue, form.content.getOrElse("")) {
Notifier.msgPullRequest(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}")
}
}
}
redirect(s"/${owner}/${name}/pull/${issueId}")
redirect(s"/${owner}/${name}/pull/${issueId}")
} else Unauthorized()
}
})
@@ -513,8 +520,7 @@ trait PullRequestsControllerBase extends ControllerBase {
private def searchPullRequests(userName: Option[String], repository: RepositoryService.RepositoryInfo) =
defining(repository.owner, repository.name){ case (owner, repoName) =>
val page = IssueSearchCondition.page(request)
val sessionKey = Keys.Session.Pulls(owner, repoName)
val page = IssueSearchCondition.page(request)
// retrieve search condition
val condition = IssueSearchCondition(request)
@@ -530,7 +536,26 @@ trait PullRequestsControllerBase extends ControllerBase {
countIssue(condition.copy(state = "closed"), true, owner -> repoName),
condition,
repository,
hasWritePermission(owner, repoName, context.loginAccount))
isEditable(repository),
isManageable(repository))
}
/**
* Tests whether an logged-in user can manage pull requests.
*/
private def isManageable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
hasWritePermission(repository.owner, repository.name, context.loginAccount)
}
/**
* Tests whether an logged-in user can post pull requests.
*/
private def isEditable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
repository.repository.options.issuesOption match {
case "PUBLIC" => hasReadPermission(repository.owner, repository.name, context.loginAccount)
case "PRIVATE" => hasWritePermission(repository.owner, repository.name, context.loginAccount)
case "DISABLE" => false
}
}
}

View File

@@ -14,10 +14,10 @@ import org.scalatra.i18n.Messages
class WikiController extends WikiControllerBase
with WikiService with RepositoryService with AccountService with ActivityService
with CollaboratorsAuthenticator with ReferrerAuthenticator
with ReadableUsersAuthenticator with CollaboratorsAuthenticator with ReferrerAuthenticator
trait WikiControllerBase extends ControllerBase {
self: WikiService with RepositoryService with ActivityService with CollaboratorsAuthenticator with ReferrerAuthenticator =>
self: WikiService with RepositoryService with ActivityService with ReadableUsersAuthenticator with CollaboratorsAuthenticator with ReferrerAuthenticator =>
case class WikiPageEditForm(pageName: String, content: String, message: Option[String], currentPageName: String, id: String)
@@ -62,7 +62,7 @@ trait WikiControllerBase extends ControllerBase {
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
JGitUtil.getCommitLog(git, "master", path = pageName + ".md") match {
case Right((logs, hasNext)) => html.history(Some(pageName), logs, repository)
case Right((logs, hasNext)) => html.history(Some(pageName), logs, repository, isEditable(repository))
case Left(_) => NotFound()
}
}
@@ -87,7 +87,7 @@ trait WikiControllerBase extends ControllerBase {
}
})
get("/:owner/:repository/wiki/:page/_revert/:commitId")(referrersOnly { repository =>
get("/:owner/:repository/wiki/:page/_revert/:commitId")(readableUsersOnly { repository =>
if(isEditable(repository)){
val pageName = StringUtil.urlDecode(params("page"))
val Array(from, to) = params("commitId").split("\\.\\.\\.")
@@ -101,7 +101,7 @@ trait WikiControllerBase extends ControllerBase {
} else Unauthorized()
})
get("/:owner/:repository/wiki/_revert/:commitId")(referrersOnly { repository =>
get("/:owner/:repository/wiki/_revert/:commitId")(readableUsersOnly { repository =>
if(isEditable(repository)){
val Array(from, to) = params("commitId").split("\\.\\.\\.")
@@ -114,14 +114,14 @@ trait WikiControllerBase extends ControllerBase {
} else Unauthorized()
})
get("/:owner/:repository/wiki/:page/_edit")(referrersOnly { repository =>
get("/:owner/:repository/wiki/:page/_edit")(readableUsersOnly { repository =>
if(isEditable(repository)){
val pageName = StringUtil.urlDecode(params("page"))
html.edit(pageName, getWikiPage(repository.owner, repository.name, pageName), repository)
} else Unauthorized()
})
post("/:owner/:repository/wiki/_edit", editForm)(referrersOnly { (form, repository) =>
post("/:owner/:repository/wiki/_edit", editForm)(readableUsersOnly { (form, repository) =>
if(isEditable(repository)){
defining(context.loginAccount.get){ loginAccount =>
saveWikiPage(
@@ -146,13 +146,13 @@ trait WikiControllerBase extends ControllerBase {
} else Unauthorized()
})
get("/:owner/:repository/wiki/_new")(referrersOnly { repository =>
get("/:owner/:repository/wiki/_new")(readableUsersOnly { repository =>
if(isEditable(repository)){
html.edit("", None, repository)
} else Unauthorized()
})
post("/:owner/:repository/wiki/_new", newForm)(referrersOnly { (form, repository) =>
post("/:owner/:repository/wiki/_new", newForm)(readableUsersOnly { (form, repository) =>
if(isEditable(repository)){
defining(context.loginAccount.get){ loginAccount =>
saveWikiPage(repository.owner, repository.name, form.currentPageName, form.pageName,
@@ -170,7 +170,7 @@ trait WikiControllerBase extends ControllerBase {
} else Unauthorized()
})
get("/:owner/:repository/wiki/:page/_delete")(referrersOnly { repository =>
get("/:owner/:repository/wiki/:page/_delete")(readableUsersOnly { repository =>
if(isEditable(repository)){
val pageName = StringUtil.urlDecode(params("page"))
@@ -182,7 +182,7 @@ trait WikiControllerBase extends ControllerBase {
}
} else Unauthorized()
})
get("/:owner/:repository/wiki/_pages")(referrersOnly { repository =>
html.pages(getWikiPageList(repository.owner, repository.name), repository, isEditable(repository))
})
@@ -190,7 +190,7 @@ trait WikiControllerBase extends ControllerBase {
get("/:owner/:repository/wiki/_history")(referrersOnly { repository =>
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
JGitUtil.getCommitLog(git, "master") match {
case Right((logs, hasNext)) => html.history(None, logs, repository)
case Right((logs, hasNext)) => html.history(None, logs, repository, isEditable(repository))
case Left(_) => NotFound()
}
}
@@ -242,7 +242,7 @@ trait WikiControllerBase extends ControllerBase {
private def isEditable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
repository.repository.options.wikiOption match {
case "ALL" => repository.repository.isPrivate == false || hasReadPermission(repository.owner, repository.name, context.loginAccount)
// case "ALL" => repository.repository.isPrivate == false || hasReadPermission(repository.owner, repository.name, context.loginAccount)
case "PUBLIC" => hasReadPermission(repository.owner, repository.name, context.loginAccount)
case "PRIVATE" => hasWritePermission(repository.owner, repository.name, context.loginAccount)
case "DISABLE" => false

View File

@@ -13,7 +13,7 @@ trait HandleCommentService {
with WebHookService with WebHookIssueCommentService with WebHookPullRequestService =>
/**
* @see [[https://github.com/takezoe/gitbucket/wiki/CommentAction]]
* @see [[https://github.com/gitbucket/gitbucket/wiki/CommentAction]]
*/
def handleComment(issue: Issue, content: Option[String], repository: RepositoryService.RepositoryInfo, actionOpt: Option[String])
(implicit context: Context, s: Session) = {
@@ -54,18 +54,20 @@ trait HandleCommentService {
// call web hooks
action match {
case None => commentId.map{ commentIdSome => callIssueCommentWebHook(repository, issue, commentIdSome, context.loginAccount.get) }
case Some(act) => val webHookAction = act match {
case "open" => "opened"
case "reopen" => "reopened"
case "close" => "closed"
case _ => act
}
if(issue.isPullRequest){
case None => commentId.map { commentIdSome => callIssueCommentWebHook(repository, issue, commentIdSome, context.loginAccount.get) }
case Some(act) => {
val webHookAction = act match {
case "open" => "opened"
case "reopen" => "reopened"
case "close" => "closed"
case _ => act
}
if (issue.isPullRequest) {
callPullRequestWebHook(webHookAction, repository, issue.issueId, context.baseUrl, context.loginAccount.get)
} else {
callIssuesWebHook(webHookAction, repository, issue, context.baseUrl, context.loginAccount.get)
}
}
}
// notifications

View File

@@ -363,15 +363,15 @@ trait RepositoryService { self: AccountService =>
val q1 = Collaborators
.innerJoin(Accounts).on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === false.bind) }
.filter { case (t1, t2) => t1.byRepository(userName, repositoryName) }
.map { case (t1, t2) => t1.collaboratorName }
.map { case (t1, t2) => (t1.collaboratorName, t1.permission) }
val q2 = Collaborators
.innerJoin(Accounts).on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === true.bind) }
.innerJoin(GroupMembers).on { case ((t1, t2), t3) => t2.userName === t3.groupName }
.filter { case ((t1, t2), t3) => t1.byRepository(userName, repositoryName) }
.map { case ((t1, t2), t3) => t3.userName }
.map { case ((t1, t2), t3) => (t3.userName, t1.permission) }
q1.union(q2).list.filter { x => filter.isEmpty || filter.exists(_.name == x) }
q1.union(q2).list.filter { x => filter.isEmpty || filter.exists(_.name == x._2) }.map(_._1)
}

View File

@@ -1,9 +1,10 @@
@(issue: gitbucket.core.model.Issue,
reopenable: Boolean,
hasWritePermission: Boolean,
isEditable: Boolean,
isManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@if(context.loginAccount.isDefined){
@if(isEditable){
<hr/><br/>
<form method="POST" validate="true">
<div class="issue-avatar-image">@helpers.avatarLink(context.loginAccount.get.userName, 48)</div>
@@ -16,7 +17,7 @@
enableRefsLink = true,
enableLineBreaks = true,
enableTaskList = true,
hasWritePermission = hasWritePermission,
hasWritePermission = isEditable,
completionContext = "issues",
style = "",
elastic = true,
@@ -24,7 +25,7 @@
)
<div class="text-right">
<input type="hidden" name="issueId" value="@issue.issueId"/>
@if((reopenable || !issue.closed) && (hasWritePermission || issue.openedUserName == context.loginAccount.get.userName)){
@if((reopenable || !issue.closed) && (isManageable || issue.openedUserName == context.loginAccount.get.userName)){
<input type="submit" class="btn btn-default" tabindex="3" formaction="@helpers.url(repository)/issue_comments/state" value="@{if(issue.closed) "Reopen" else "Close"}" id="action"/>
}
<input type="submit" class="btn btn-success" tabindex="2" formaction="@helpers.url(repository)/issue_comments/new" value="Comment"/>

View File

@@ -1,6 +1,6 @@
@(issue: Option[gitbucket.core.model.Issue],
comments: List[gitbucket.core.model.Comment],
hasWritePermission: Boolean,
isManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
pullreq: Option[gitbucket.core.model.PullRequest] = None)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@@ -11,7 +11,7 @@
<div class="panel-heading">
@helpers.user(issue.get.openedUserName, styleClass="username strong") <span class="muted">commented @gitbucket.core.helper.html.datetimeago(issue.get.registeredDate)</span>
<span class="pull-right">
@if(hasWritePermission || context.loginAccount.map(_.userName == issue.get.openedUserName).getOrElse(false)){
@if(isManageable || context.loginAccount.map(_.userName == issue.get.openedUserName).getOrElse(false)){
<a href="#" data-issue-id="@issue.get.issueId"><i class="octicon octicon-pencil" aria-label="Edit"></i></a>
}
</span>
@@ -24,7 +24,7 @@
enableRefsLink = true,
enableLineBreaks = true,
enableTaskList = true,
hasWritePermission = hasWritePermission
hasWritePermission = isManageable
)
</div>
</div>
@@ -48,7 +48,7 @@
@gitbucket.core.helper.html.datetimeago(comment.registeredDate)
</span>
@if(comment.action != "commit" && comment.action != "merge" && comment.action != "refer"
&& (hasWritePermission || context.loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false))){
&& (isManageable || context.loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false))){
<span class="pull-right">
<a href="#" data-comment-id="@comment.commentId"><i class="octicon octicon-pencil" aria-label="Edit"></i></a>&nbsp;
<a href="#" data-comment-id="@comment.commentId"><i class="octicon octicon-x" aria-label="Remove"></i></a>
@@ -63,7 +63,7 @@
enableRefsLink = true,
enableLineBreaks = true,
enableTaskList = true,
hasWritePermission = hasWritePermission
hasWritePermission = isManageable
)
</div>
</div>
@@ -166,7 +166,7 @@
}
}
case comment: CommitComment => {
@gitbucket.core.helper.html.commitcomment(comment, hasWritePermission, repository, pullreq.map(_.commitIdTo))
@gitbucket.core.helper.html.commitcomment(comment, isManageable, repository, pullreq.map(_.commitIdTo))
}
}
<script>

View File

@@ -1,7 +1,7 @@
@(collaborators: List[String],
milestones: List[gitbucket.core.model.Milestone],
labels: List[gitbucket.core.model.Label],
hasWritePermission: Boolean,
isManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@gitbucket.core.html.main(s"New Issue - ${repository.owner}/${repository.name}", Some(repository)){
@@ -18,7 +18,7 @@
enableRefsLink = true,
enableLineBreaks = true,
enableTaskList = true,
hasWritePermission = hasWritePermission,
hasWritePermission = isManageable,
completionContext = "issues",
style = "height: 200px; max-height: 250px;",
elastic = true
@@ -28,7 +28,7 @@
</div>
</div>
<div class="col-md-3">
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map(x => (x, 0, 0)), labels, hasWritePermission, repository)
@gitbucket.core.issues.html.issueinfo(None, Nil, Nil, collaborators, milestones.map(x => (x, 0, 0)), labels, isManageable, repository)
</div>
</div>
</form>

View File

@@ -4,14 +4,15 @@
collaborators: List[String],
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
labels: List[gitbucket.core.model.Label],
hasWritePermission: Boolean,
isEditable: Boolean,
isManageable: 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)){
@gitbucket.core.html.menu("issues", repository){
<div>
<div class="show-title pull-right">
@if(hasWritePermission || context.loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)){
@if(isManageable || context.loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)){
<a class="btn btn-default" href="#" id="edit">Edit</a>
}
<a class="btn btn-success" href="@helpers.url(repository)/issues/new">New issue</a>
@@ -47,11 +48,11 @@
<hr>
<div style="margin-top: 15px;">
<div class="col-md-9">
@gitbucket.core.issues.html.commentlist(Some(issue), comments, hasWritePermission, repository)
@gitbucket.core.issues.html.commentform(issue, true, hasWritePermission, repository)
@gitbucket.core.issues.html.commentlist(Some(issue), comments, isManageable, repository)
@gitbucket.core.issues.html.commentform(issue, true, isEditable, isManageable, repository)
</div>
<div class="col-md-3">
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, isManageable, repository)
</div>
</div>
}

View File

@@ -4,12 +4,12 @@
collaborators: List[String],
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
labels: List[gitbucket.core.model.Label],
hasWritePermission: Boolean,
isManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
<div style="margin-bottom: 14px;">
<span class="muted small strong">Labels</span>
@if(hasWritePermission){
@if(isManageable){
<div class="pull-right">
@gitbucket.core.helper.html.dropdown("Edit", right = true) {
@labels.map { label =>
@@ -34,7 +34,7 @@
<hr/>
<div style="margin-bottom: 14px;">
<span class="muted small strong">Milestone</span>
@if(hasWritePermission){
@if(isManageable){
<div class="pull-right">
@gitbucket.core.helper.html.dropdown("Edit", right = true) {
<li><a href="javascript:void(0);" class="milestone" data-id=""><i class="octicon octicon-x"></i> Clear this milestone</a></li>
@@ -86,7 +86,7 @@
<hr/>
<div style="margin-bottom: 14px;">
<span class="muted small strong">Assignee</span>
@if(hasWritePermission){
@if(isManageable){
<div class="pull-right">
@gitbucket.core.helper.html.dropdown("Edit", right = true) {
<li><a href="javascript:void(0);" class="assign" data-name=""><i class="octicon octicon-x"></i> Clear assignee</a></li>

View File

@@ -8,7 +8,8 @@
closedCount: Int,
condition: gitbucket.core.service.IssuesService.IssueSearchCondition,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
hasWritePermission: Boolean)(implicit context: gitbucket.core.controller.Context)
isEditable: Boolean,
isManageable: Boolean)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@gitbucket.core.html.main((if(target == "issues") "Issues" else "Pull requests") + s" - ${repository.owner}/${repository.name}", Some(repository)){
@gitbucket.core.html.menu(target, repository){
@@ -21,7 +22,7 @@
</li>
</ul>
<form method="GET" id="search-filter-form" class="form-inline pull-right">
@if(context.loginAccount.isDefined){
@if(isEditable){
@if(target == "issues"){
<a class="btn btn-success" href="@helpers.url(repository)/issues/new">New issue</a>
}
@@ -30,8 +31,8 @@
}
}
</form>
@gitbucket.core.issues.html.listparts(target, issues, page, openCount, closedCount, condition, collaborators, milestones, labels, Some(repository), hasWritePermission)
@if(hasWritePermission){
@gitbucket.core.issues.html.listparts(target, issues, page, openCount, closedCount, condition, collaborators, milestones, labels, Some(repository), isManageable)
@if(isManageable){
<form id="batcheditForm" method="POST">
<input type="hidden" name="value"/>
<input type="hidden" name="checked"/>
@@ -40,7 +41,7 @@
}
}
}
@if(hasWritePermission){
@if(isManageable){
<script>
$(function(){
$('a.header-link').mouseover(function(e){

View File

@@ -8,7 +8,7 @@
milestones: List[gitbucket.core.model.Milestone] = Nil,
labels: List[gitbucket.core.model.Label] = Nil,
repository: Option[gitbucket.core.service.RepositoryService.RepositoryInfo] = None,
hasWritePermission: Boolean = false)(implicit context: gitbucket.core.controller.Context)
isManageable: Boolean = false)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@import gitbucket.core.service.IssuesService.IssueInfo
@*
@@ -110,7 +110,7 @@
</li>
}
</span>
@if(hasWritePermission){
@if(isManageable){
<span id="table-issues-batchedit">
@gitbucket.core.helper.html.dropdown("Mark as") {
<li><a href="javascript:void(0);" class="toggle-state" data-id="open">Open</a></li>
@@ -174,7 +174,7 @@
@issues.map { case IssueInfo(issue, labels, milestone, commentCount, commitStatus) =>
<tr>
<td style="padding-top: 12px; padding-bottom: 12px;">
@if(hasWritePermission){
@if(isManageable){
<input type="checkbox" value="@issue.issueId"/>
}
@*

View File

@@ -5,12 +5,13 @@
collaborators: List[String],
milestones: List[(gitbucket.core.model.Milestone, Int, Int)],
labels: List[gitbucket.core.model.Label],
hasWritePermission: Boolean,
isEditable: Boolean,
isManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
<div class="col-md-9">
<div id="comment-list">
@gitbucket.core.issues.html.commentlist(Some(issue), comments, hasWritePermission, repository, Some(pullreq))
@gitbucket.core.issues.html.commentlist(Some(issue), comments, isManageable, repository, Some(pullreq))
</div>
@defining(comments.flatMap {
case comment: gitbucket.core.model.IssueComment => Some(comment)
@@ -25,7 +26,7 @@
</div>
</div>
}
@if(hasWritePermission && issue.closed && pullreq.userName == pullreq.requestUserName && merged &&
@if(isManageable && issue.closed && pullreq.userName == pullreq.requestUserName && merged &&
pullreq.repositoryName == pullreq.requestRepositoryName && repository.branchList.contains(pullreq.requestBranch)){
<div class="issue-comment-box" style="background-color: #d0eeff;">
<div class="box-content"class="issue-content" style="border: 1px solid #87a8c9; padding: 10px;">
@@ -37,11 +38,11 @@
</div>
</div>
}
@gitbucket.core.issues.html.commentform(issue, !merged, hasWritePermission, repository)
@gitbucket.core.issues.html.commentform(issue, !merged, isEditable, isManageable, repository)
}
</div>
<div class="col-md-3">
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
@gitbucket.core.issues.html.issueinfo(Some(issue), comments, issueLabels, collaborators, milestones, labels, isManageable, repository)
</div>
<script>
$(function(){
@@ -55,7 +56,7 @@ $(function(){
$.get('@helpers.url(repository)/pull/@issue.issueId/mergeguide', function(data){ $('.check-conflict').html(data); });
}
@if(hasWritePermission){
@if(isManageable){
$('.delete-branch').click(function(e){
var branchName = $(e.target).data('name');
return confirm('Are you sure you want to remove the ' + branchName + ' branch?');

View File

@@ -7,7 +7,8 @@
labels: List[gitbucket.core.model.Label],
dayByDayCommits: Seq[Seq[gitbucket.core.util.JGitUtil.CommitInfo]],
diffs: Seq[gitbucket.core.util.JGitUtil.DiffInfo],
hasWritePermission: Boolean,
isEditable: Boolean,
isManageable: Boolean,
repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
flash: Map[String, String])(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@@ -18,7 +19,7 @@
@defining(dayByDayCommits.flatten){ commits =>
<div>
<div class="show-title pull-right">
@if(hasWritePermission || context.loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)){
@if(isManageable || context.loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)){
<a class="btn" href="#" id="edit">Edit</a>
}
@if(context.loginAccount.isDefined){
@@ -82,13 +83,13 @@
@flash.get("info").map{ info =>
<div class="alert alert-info">@info</div>
}
@gitbucket.core.pulls.html.conversation(issue, pullreq, comments, issueLabels, collaborators, milestones, labels, hasWritePermission, repository)
@gitbucket.core.pulls.html.conversation(issue, pullreq, comments, issueLabels, collaborators, milestones, labels, isEditable, isManageable, repository)
</div>
<div class="tab-pane" id="commits">
@gitbucket.core.pulls.html.commits(dayByDayCommits, Some(comments), repository)
</div>
<div class="tab-pane" id="files">
@gitbucket.core.helper.html.diff(diffs, repository, Some(commits.head.id), Some(commits.last.id), true, Some(pullreq.issueId), hasWritePermission, true)
@gitbucket.core.helper.html.diff(diffs, repository, Some(commits.head.id), Some(commits.last.id), true, Some(pullreq.issueId), isManageable, true)
</div>
</div>
}

View File

@@ -69,11 +69,6 @@
<input type="radio" name="issuesOption" value="PUBLIC" @if(repository.repository.options.issuesOption == "PUBLIC"){ checked}> Readable users can view, create and comment on isues
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="issuesOption" value="ALL" @if(repository.repository.options.issuesOption == "ALL"){ checked}> Anyone can view, create and comment on issues
</label>
</div>
<label for="externalIssuesUrl" class="strong">External URL:
<span class="normal muted">(Put if you have the external issue tracking system for this project)</span>
</label>
@@ -100,11 +95,6 @@
<input type="radio" name="wikiOption" value="PUBLIC" @if(repository.repository.options.wikiOption == "PUBLIC"){ checked}> Readable users can view, create and edit wiki pages
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="wikiOption" value="ALL" @if(repository.repository.options.wikiOption == "ALL"){ checked}> Anyone can view, create and edit wiki pages
</label>
</div>
<label for="externalWikiUrl" class="strong">External URL:
<span class="normal muted">(Put if you have the external Wiki for this project)</span>
</label>

View File

@@ -44,7 +44,7 @@
</form>
}
}
<script>
<script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script><script>
$(function(){
try {
$('.clickable').dropzone({

View File

@@ -1,21 +1,20 @@
@(pageName: Option[String],
commits: List[gitbucket.core.util.JGitUtil.CommitInfo],
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
repository: gitbucket.core.service.RepositoryService.RepositoryInfo,
isEditable: Boolean)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@gitbucket.core.html.main(s"History - ${repository.owner}/${repository.name}", Some(repository)){
@gitbucket.core.html.menu("wiki", repository){
<div class="pull-right">
@if(pageName.isEmpty){
@if(context.loginAccount.isDefined){
<a class="btn btn-small" href="@helpers.url(repository)/wiki/_new">New Page</a>
}
} else {
@if(context.loginAccount.isDefined){
<a class="btn btn-small btn-default" href="@helpers.url(repository)/wiki/@helpers.urlEncode(pageName)/_edit">Edit Page</a>
<a class="btn btn-small btn-success" href="@helpers.url(repository)/wiki/_new">New Page</a>
}
@if(isEditable) {
<div class="pull-right">
@if(pageName.isEmpty) {
<a class="btn btn-small" href="@helpers.url(repository)/wiki/_new">New Page</a>
} else {
<a class="btn btn-small btn-default" href="@helpers.url(repository)/wiki/@helpers.urlEncode(pageName)/_edit">Edit Page</a>
<a class="btn btn-small btn-success" href="@helpers.url(repository)/wiki/_new">New Page</a>
}
</div>
}
</div>
<h1 class="wiki-title">
@if(pageName.isEmpty){
<span class="muted">History</span>