Use ControlUtil.

This commit is contained in:
takezoe
2013-09-22 19:28:14 +09:00
parent 602b6c635a
commit fd8b5780f3
7 changed files with 299 additions and 323 deletions

View File

@@ -1,6 +1,8 @@
package app package app
import _root_.util.Directory._ import _root_.util.Directory._
import _root_.util.Implicits._
import _root_.util.ControlUtil._
import _root_.util.{FileUtil, Validations} import _root_.util.{FileUtil, Validations}
import org.scalatra._ import org.scalatra._
import org.scalatra.json._ import org.scalatra.json._
@@ -57,56 +59,51 @@ abstract class ControllerBase extends ScalatraFilter
*/ */
implicit def context: Context = Context(servletContext.getContextPath, LoginAccount, currentURL, request) implicit def context: Context = Context(servletContext.getContextPath, LoginAccount, currentURL, request)
private def currentURL: String = { private def currentURL: String = defining(request.getQueryString){ queryString =>
val queryString = request.getQueryString
request.getRequestURI + (if(queryString != null) "?" + queryString else "") request.getRequestURI + (if(queryString != null) "?" + queryString else "")
} }
private def LoginAccount: Option[Account] = { private def LoginAccount: Option[Account] =
session.get("LOGIN_ACCOUNT") match { session.get("LOGIN_ACCOUNT") match {
case Some(x: Account) => Some(x) case Some(x: Account) => Some(x)
case _ => None case _ => None
} }
}
def ajaxGet(path : String)(action : => Any) : Route = { def ajaxGet(path : String)(action : => Any) : Route =
super.get(path){ super.get(path){
request.setAttribute("AJAX", "true") request.setAttribute("AJAX", "true")
action action
} }
}
override def ajaxGet[T](path : String, form : MappingValueType[T])(action : T => Any) : Route = { override def ajaxGet[T](path : String, form : MappingValueType[T])(action : T => Any) : Route =
super.ajaxGet(path, form){ form => super.ajaxGet(path, form){ form =>
request.setAttribute("AJAX", "true") request.setAttribute("AJAX", "true")
action(form) action(form)
} }
}
def ajaxPost(path : String)(action : => Any) : Route = { def ajaxPost(path : String)(action : => Any) : Route =
super.post(path){ super.post(path){
request.setAttribute("AJAX", "true") request.setAttribute("AJAX", "true")
action action
} }
}
override def ajaxPost[T](path : String, form : MappingValueType[T])(action : T => Any) : Route = { override def ajaxPost[T](path : String, form : MappingValueType[T])(action : T => Any) : Route =
super.ajaxPost(path, form){ form => super.ajaxPost(path, form){ form =>
request.setAttribute("AJAX", "true") request.setAttribute("AJAX", "true")
action(form) action(form)
} }
}
protected def NotFound() = { protected def NotFound() =
if(request.getAttribute("AJAX") == null){ if(request.hasAttribute("AJAX")){
org.scalatra.NotFound(html.error("Not Found"))
} else {
org.scalatra.NotFound() org.scalatra.NotFound()
} } else {
org.scalatra.NotFound(html.error("Not Found"))
} }
protected def Unauthorized()(implicit context: app.Context) = { protected def Unauthorized()(implicit context: app.Context) =
if(request.getAttribute("AJAX") == null){ if(request.hasAttribute("AJAX")){
org.scalatra.Unauthorized()
} else {
if(context.loginAccount.isDefined){ if(context.loginAccount.isDefined){
org.scalatra.Unauthorized(redirect("/")) org.scalatra.Unauthorized(redirect("/"))
} else { } else {
@@ -116,13 +113,9 @@ abstract class ControllerBase extends ScalatraFilter
org.scalatra.Unauthorized(redirect("/signin?redirect=" + currentURL)) org.scalatra.Unauthorized(redirect("/signin?redirect=" + currentURL))
} }
} }
} else {
org.scalatra.Unauthorized()
}
} }
protected def baseUrl = { protected def baseUrl = defining(request.getRequestURL.toString){ url =>
val url = request.getRequestURL.toString
url.substring(0, url.length - (request.getRequestURI.length - request.getContextPath.length)) url.substring(0, url.length - (request.getRequestURI.length - request.getContextPath.length))
} }
@@ -133,13 +126,11 @@ abstract class ControllerBase extends ScalatraFilter
*/ */
case class Context(path: String, loginAccount: Option[Account], currentUrl: String, request: HttpServletRequest){ case class Context(path: String, loginAccount: Option[Account], currentUrl: String, request: HttpServletRequest){
def redirectUrl = { def redirectUrl = if(request.getParameter("redirect") != null){
if(request.getParameter("redirect") != null){
request.getParameter("redirect") request.getParameter("redirect")
} else { } else {
currentUrl currentUrl
} }
}
/** /**
* Get object from cache. * Get object from cache.
@@ -147,13 +138,12 @@ case class Context(path: String, loginAccount: Option[Account], currentUrl: Stri
* If object has not been cached with the specified key then retrieves by given action. * If object has not been cached with the specified key then retrieves by given action.
* Cached object are available during a request. * Cached object are available during a request.
*/ */
def cache[A](key: String)(action: => A): A = { def cache[A](key: String)(action: => A): A =
Option(request.getAttribute("cache." + key).asInstanceOf[A]).getOrElse { Option(request.getAttribute("cache." + key).asInstanceOf[A]).getOrElse {
val newObject = action val newObject = action
request.setAttribute("cache." + key, newObject) request.setAttribute("cache." + key, newObject)
newObject newObject
} }
}
} }
@@ -163,7 +153,7 @@ case class Context(path: String, loginAccount: Option[Account], currentUrl: Stri
trait AccountManagementControllerBase extends ControllerBase with FileUploadControllerBase { trait AccountManagementControllerBase extends ControllerBase with FileUploadControllerBase {
self: AccountService => self: AccountService =>
protected def updateImage(userName: String, fileId: Option[String], clearImage: Boolean): Unit = { protected def updateImage(userName: String, fileId: Option[String], clearImage: Boolean): Unit =
if(clearImage){ if(clearImage){
getAccountByUserName(userName).flatMap(_.image).map { image => getAccountByUserName(userName).flatMap(_.image).map { image =>
new java.io.File(getUserUploadDir(userName), image).delete() new java.io.File(getUserUploadDir(userName), image).delete()
@@ -179,7 +169,6 @@ trait AccountManagementControllerBase extends ControllerBase with FileUploadCont
updateAvatarImage(userName, Some(filename)) updateAvatarImage(userName, Some(filename))
} }
} }
}
protected def uniqueUserName: Constraint = new Constraint(){ protected def uniqueUserName: Constraint = new Constraint(){
override def validate(name: String, value: String): Option[String] = override def validate(name: String, value: String): Option[String] =
@@ -212,11 +201,10 @@ trait FileUploadControllerBase {
// def removeTemporaryFile(fileId: String)(implicit session: HttpSession): Unit = // def removeTemporaryFile(fileId: String)(implicit session: HttpSession): Unit =
// getTemporaryFile(fileId).delete() // getTemporaryFile(fileId).delete()
def removeTemporaryFiles()(implicit session: HttpSession): Unit = def removeTemporaryFiles()(implicit session: HttpSession): Unit = FileUtils.deleteDirectory(TemporaryDir)
FileUtils.deleteDirectory(TemporaryDir)
def getUploadedFilename(fileId: String)(implicit session: HttpSession): Option[String] = { def getUploadedFilename(fileId: String)(implicit session: HttpSession): Option[String] =
val filename = Option(session.getAttribute("upload_" + fileId).asInstanceOf[String]) defining(Option(session.getAttribute("upload_" + fileId).asInstanceOf[String])){ filename =>
if(filename.isDefined){ if(filename.isDefined){
session.removeAttribute("upload_" + fileId) session.removeAttribute("upload_" + fileId)
} }

View File

@@ -2,6 +2,7 @@ package app
import service._ import service._
import util.UsersAuthenticator import util.UsersAuthenticator
import util.Implicits._
class DashboardController extends DashboardControllerBase class DashboardController extends DashboardControllerBase
with IssuesService with PullRequestService with RepositoryService with AccountService with IssuesService with PullRequestService with RepositoryService with AccountService
@@ -43,11 +44,10 @@ trait DashboardControllerBase extends ControllerBase {
// condition // condition
val sessionKey = "dashboard/issues" val sessionKey = "dashboard/issues"
val condition = if(request.getQueryString == null) val condition = session.putAndGet(sessionKey,
session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition] if(request.hasQueryString) IssueSearchCondition(request)
else IssueSearchCondition(request) else session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition]
)
session.put(sessionKey, condition)
val userName = context.loginAccount.get.userName val userName = context.loginAccount.get.userName
val repositories = getUserRepositories(userName, baseUrl).map(repo => repo.owner -> repo.name) val repositories = getUserRepositories(userName, baseUrl).map(repo => repo.owner -> repo.name)
@@ -76,14 +76,10 @@ trait DashboardControllerBase extends ControllerBase {
// condition // condition
val sessionKey = "dashboard/pulls" val sessionKey = "dashboard/pulls"
val condition = { val condition = session.putAndGet(sessionKey, {
if(request.getQueryString == null) if(request.hasQueryString) IssueSearchCondition(request)
session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition] else session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition]
else }.copy(repo = repository))
IssueSearchCondition(request)
}.copy(repo = repository)
session.put(sessionKey, condition)
val userName = context.loginAccount.get.userName val userName = context.loginAccount.get.userName
val repositories = getUserRepositories(userName, baseUrl).map(repo => repo.owner -> repo.name) val repositories = getUserRepositories(userName, baseUrl).map(repo => repo.owner -> repo.name)

View File

@@ -5,6 +5,8 @@ import jp.sf.amateras.scalatra.forms._
import service._ import service._
import IssuesService._ import IssuesService._
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, ReadableUsersAuthenticator, Notifier} import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, ReadableUsersAuthenticator, Notifier}
import util.Implicits._
import util.ControlUtil._
import org.scalatra.Ok import org.scalatra.Ok
class IssuesController extends IssuesControllerBase class IssuesController extends IssuesControllerBase
@@ -57,10 +59,7 @@ trait IssuesControllerBase extends ControllerBase {
}) })
get("/:owner/:repository/issues/:id")(referrersOnly { repository => get("/:owner/:repository/issues/:id")(referrersOnly { repository =>
val owner = repository.owner defining(repository.owner, repository.name, params("id")){ case (owner, name, issueId) =>
val name = repository.name
val issueId = params("id")
getIssue(owner, name, issueId) map { getIssue(owner, name, issueId) map {
issues.html.issue( issues.html.issue(
_, _,
@@ -72,23 +71,22 @@ trait IssuesControllerBase extends ControllerBase {
hasWritePermission(owner, name, context.loginAccount), hasWritePermission(owner, name, context.loginAccount),
repository) repository)
} getOrElse NotFound } getOrElse NotFound
}
}) })
get("/:owner/:repository/issues/new")(readableUsersOnly { repository => get("/:owner/:repository/issues/new")(readableUsersOnly { repository =>
val owner = repository.owner defining(repository.owner, repository.name){ case (owner, name) =>
val name = repository.name
issues.html.create( issues.html.create(
(getCollaborators(owner, name) :+ owner).sorted, (getCollaborators(owner, name) :+ owner).sorted,
getMilestones(owner, name), getMilestones(owner, name),
getLabels(owner, name), getLabels(owner, name),
hasWritePermission(owner, name, context.loginAccount), hasWritePermission(owner, name, context.loginAccount),
repository) repository)
}
}) })
post("/:owner/:repository/issues/new", issueCreateForm)(readableUsersOnly { (form, repository) => post("/:owner/:repository/issues/new", issueCreateForm)(readableUsersOnly { (form, repository) =>
val owner = repository.owner defining(repository.owner, repository.name){ case (owner, name) =>
val name = repository.name
val writable = hasWritePermission(owner, name, context.loginAccount) val writable = hasWritePermission(owner, name, context.loginAccount)
val userName = context.loginAccount.get.userName val userName = context.loginAccount.get.userName
@@ -118,18 +116,18 @@ trait IssuesControllerBase extends ControllerBase {
} }
redirect(s"/${owner}/${name}/issues/${issueId}") redirect(s"/${owner}/${name}/issues/${issueId}")
}
}) })
ajaxPost("/:owner/:repository/issues/edit/:id", issueEditForm)(readableUsersOnly { (form, repository) => ajaxPost("/:owner/:repository/issues/edit/:id", issueEditForm)(readableUsersOnly { (form, repository) =>
val owner = repository.owner defining(repository.owner, repository.name){ case (owner, name) =>
val name = repository.name
getIssue(owner, name, params("id")).map { issue => getIssue(owner, name, params("id")).map { issue =>
if(isEditable(owner, name, issue.openedUserName)){ if(isEditable(owner, name, issue.openedUserName)){
updateIssue(owner, name, issue.issueId, form.title, form.content) updateIssue(owner, name, issue.issueId, form.title, form.content)
redirect(s"/${owner}/${name}/issues/_data/${issue.issueId}") redirect(s"/${owner}/${name}/issues/_data/${issue.issueId}")
} else Unauthorized } else Unauthorized
} getOrElse NotFound } getOrElse NotFound
}
}) })
post("/:owner/:repository/issue_comments/new", commentForm)(readableUsersOnly { (form, repository) => post("/:owner/:repository/issue_comments/new", commentForm)(readableUsersOnly { (form, repository) =>
@@ -147,15 +145,14 @@ trait IssuesControllerBase extends ControllerBase {
}) })
ajaxPost("/:owner/:repository/issue_comments/edit/:id", commentForm)(readableUsersOnly { (form, repository) => ajaxPost("/:owner/:repository/issue_comments/edit/:id", commentForm)(readableUsersOnly { (form, repository) =>
val owner = repository.owner defining(repository.owner, repository.name){ case (owner, name) =>
val name = repository.name
getComment(owner, name, params("id")).map { comment => getComment(owner, name, params("id")).map { comment =>
if(isEditable(owner, name, comment.commentedUserName)){ if(isEditable(owner, name, comment.commentedUserName)){
updateComment(comment.commentId, form.content) updateComment(comment.commentId, form.content)
redirect(s"/${owner}/${name}/issue_comments/_data/${comment.commentId}") redirect(s"/${owner}/${name}/issue_comments/_data/${comment.commentId}")
} else Unauthorized } else Unauthorized
} getOrElse NotFound } getOrElse NotFound
}
}) })
ajaxGet("/:owner/:repository/issues/_data/:id")(readableUsersOnly { repository => ajaxGet("/:owner/:repository/issues/_data/:id")(readableUsersOnly { repository =>
@@ -194,17 +191,17 @@ trait IssuesControllerBase extends ControllerBase {
}) })
ajaxPost("/:owner/:repository/issues/:id/label/new")(collaboratorsOnly { repository => ajaxPost("/:owner/:repository/issues/:id/label/new")(collaboratorsOnly { repository =>
val issueId = params("id").toInt defining(params("id").toInt){ issueId =>
registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt) registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt)
issues.html.labellist(getIssueLabels(repository.owner, repository.name, issueId)) issues.html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
}
}) })
ajaxPost("/:owner/:repository/issues/:id/label/delete")(collaboratorsOnly { repository => ajaxPost("/:owner/:repository/issues/:id/label/delete")(collaboratorsOnly { repository =>
val issueId = params("id").toInt defining(params("id").toInt){ issueId =>
deleteIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt) deleteIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt)
issues.html.labellist(getIssueLabels(repository.owner, repository.name, issueId)) issues.html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
}
}) })
ajaxPost("/:owner/:repository/issues/:id/assign")(collaboratorsOnly { repository => ajaxPost("/:owner/:repository/issues/:id/assign")(collaboratorsOnly { repository =>
@@ -223,37 +220,37 @@ trait IssuesControllerBase extends ControllerBase {
}) })
post("/:owner/:repository/issues/batchedit/state")(collaboratorsOnly { repository => post("/:owner/:repository/issues/batchedit/state")(collaboratorsOnly { repository =>
val action = params.get("value") defining(params.get("value")){ action =>
executeBatch(repository) { executeBatch(repository) {
handleComment(_, None, repository)( _ => action) handleComment(_, None, repository)( _ => action)
} }
}
}) })
post("/:owner/:repository/issues/batchedit/label")(collaboratorsOnly { repository => post("/:owner/:repository/issues/batchedit/label")(collaboratorsOnly { repository =>
val labelId = params("value").toInt defining(params("value").toInt){ labelId =>
executeBatch(repository) { issueId => executeBatch(repository) { issueId =>
getIssueLabel(repository.owner, repository.name, issueId, labelId) getOrElse { getIssueLabel(repository.owner, repository.name, issueId, labelId) getOrElse {
registerIssueLabel(repository.owner, repository.name, issueId, labelId) registerIssueLabel(repository.owner, repository.name, issueId, labelId)
} }
} }
}
}) })
post("/:owner/:repository/issues/batchedit/assign")(collaboratorsOnly { repository => post("/:owner/:repository/issues/batchedit/assign")(collaboratorsOnly { repository =>
val value = assignedUserName("value") defining(assignedUserName("value")){ value =>
executeBatch(repository) { executeBatch(repository) {
updateAssignedUserName(repository.owner, repository.name, _, value) updateAssignedUserName(repository.owner, repository.name, _, value)
} }
}
}) })
post("/:owner/:repository/issues/batchedit/milestone")(collaboratorsOnly { repository => post("/:owner/:repository/issues/batchedit/milestone")(collaboratorsOnly { repository =>
val value = milestoneId("value") defining(milestoneId("value")){ value =>
executeBatch(repository) { executeBatch(repository) {
updateMilestoneId(repository.owner, repository.name, _, value) updateMilestoneId(repository.owner, repository.name, _, value)
} }
}
}) })
val assignedUserName = (key: String) => params.get(key) filter (_.trim != "") val assignedUserName = (key: String) => params.get(key) filter (_.trim != "")
@@ -273,8 +270,8 @@ trait IssuesControllerBase extends ControllerBase {
private def handleComment(issueId: Int, content: Option[String], repository: RepositoryService.RepositoryInfo) private def handleComment(issueId: Int, content: Option[String], repository: RepositoryService.RepositoryInfo)
(getAction: model.Issue => Option[String] = (getAction: model.Issue => Option[String] =
p1 => params.get("action").filter(_ => isEditable(p1.userName, p1.repositoryName, p1.openedUserName))) = { p1 => params.get("action").filter(_ => isEditable(p1.userName, p1.repositoryName, p1.openedUserName))) = {
val owner = repository.owner
val name = repository.name defining(repository.owner, repository.name){ case (owner, name) =>
val userName = context.loginAccount.get.userName val userName = context.loginAccount.get.userName
getIssue(owner, name, issueId.toString) map { issue => getIssue(owner, name, issueId.toString) map { issue =>
@@ -325,20 +322,19 @@ trait IssuesControllerBase extends ControllerBase {
issue -> commentId issue -> commentId
} }
} }
}
private def searchIssues(filter: String, repository: RepositoryService.RepositoryInfo) = { private def searchIssues(filter: String, repository: RepositoryService.RepositoryInfo) = {
val owner = repository.owner defining(repository.owner, repository.name){ case (owner, repoName) =>
val repoName = repository.name
val filterUser = Map(filter -> params.getOrElse("userName", "")) val filterUser = Map(filter -> params.getOrElse("userName", ""))
val page = IssueSearchCondition.page(request) val page = IssueSearchCondition.page(request)
val sessionKey = s"${owner}/${repoName}/issues" val sessionKey = s"${owner}/${repoName}/issues"
// retrieve search condition // retrieve search condition
val condition = if(request.getQueryString == null){ val condition = session.putAndGet(sessionKey,
session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition] if(request.hasQueryString) IssueSearchCondition(request)
} else IssueSearchCondition(request) else session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition]
)
session.put(sessionKey, condition)
issues.html.list( issues.html.list(
searchIssue(condition, filterUser, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName), searchIssue(condition, filterUser, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName),
@@ -357,5 +353,6 @@ trait IssuesControllerBase extends ControllerBase {
repository, repository,
hasWritePermission(owner, repoName, context.loginAccount)) hasWritePermission(owner, repoName, context.loginAccount))
} }
}
} }

View File

@@ -63,14 +63,9 @@ trait PullRequestsControllerBase extends ControllerBase {
}) })
get("/:owner/:repository/pull/:id")(referrersOnly { repository => get("/:owner/:repository/pull/:id")(referrersOnly { repository =>
val owner = repository.owner defining(repository.owner, repository.name, params("id").toInt){ case (owner, name, issueId) =>
val name = repository.name
val issueId = params("id").toInt
getPullRequest(owner, name, issueId) map { case(issue, pullreq) => getPullRequest(owner, name, issueId) map { case(issue, pullreq) =>
using(Git.open(getRepositoryDir(owner, name))){ git => using(Git.open(getRepositoryDir(owner, name))){ git =>
val requestCommitId = git.getRepository.resolve(pullreq.requestBranch)
val (commits, diffs) = val (commits, diffs) =
getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo) getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo)
@@ -90,34 +85,33 @@ trait PullRequestsControllerBase extends ControllerBase {
repository, repository,
s"${baseUrl}${context.path}/git/${pullreq.requestUserName}/${pullreq.requestRepositoryName}.git") s"${baseUrl}${context.path}/git/${pullreq.requestUserName}/${pullreq.requestRepositoryName}.git")
} }
} getOrElse NotFound } getOrElse NotFound
}
}) })
post("/:owner/:repository/pull/:id/merge", mergeForm)(collaboratorsOnly { (form, repository) => post("/:owner/:repository/pull/:id/merge", mergeForm)(collaboratorsOnly { (form, repository) =>
LockUtil.lock(s"${repository.owner}/${repository.name}/merge"){ defining(repository.owner, repository.name, params("id").toInt){ case (owner, name, issueId) =>
val issueId = params("id").toInt LockUtil.lock(s"${owner}/${name}/merge"){
getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
getPullRequest(repository.owner, repository.name, issueId).map { case (issue, pullreq) => val remote = getRepositoryDir(owner, name)
val remote = getRepositoryDir(repository.owner, repository.name) val tmpdir = new java.io.File(getTemporaryDir(owner, name), s"merge-${issueId}")
val tmpdir = new java.io.File(getTemporaryDir(repository.owner, repository.name), s"merge-${issueId}")
val git = Git.cloneRepository.setDirectory(tmpdir).setURI(remote.toURI.toString).setBranch(pullreq.branch).call val git = Git.cloneRepository.setDirectory(tmpdir).setURI(remote.toURI.toString).setBranch(pullreq.branch).call
try { try {
// mark issue as merged and close. // mark issue as merged and close.
val loginAccount = context.loginAccount.get val loginAccount = context.loginAccount.get
createComment(repository.owner, repository.name, loginAccount.userName, issueId, form.message, "merge") createComment(owner, name, loginAccount.userName, issueId, form.message, "merge")
createComment(repository.owner, repository.name, loginAccount.userName, issueId, "Close", "close") createComment(owner, name, loginAccount.userName, issueId, "Close", "close")
updateClosed(repository.owner, repository.name, issueId, true) updateClosed(owner, name, issueId, true)
// record activity // record activity
recordMergeActivity(repository.owner, repository.name, loginAccount.userName, issueId, form.message) recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)
// fetch pull request to temporary working repository // fetch pull request to temporary working repository
val pullRequestBranchName = s"gitbucket-pullrequest-${issueId}" val pullRequestBranchName = s"gitbucket-pullrequest-${issueId}"
git.fetch git.fetch
.setRemote(getRepositoryDir(repository.owner, repository.name).toURI.toString) .setRemote(getRepositoryDir(owner, name).toURI.toString)
.setRefSpecs(new RefSpec(s"refs/pull/${issueId}/head:refs/heads/${pullRequestBranchName}")).call .setRefSpecs(new RefSpec(s"refs/pull/${issueId}/head:refs/heads/${pullRequestBranchName}")).call
// merge pull request // merge pull request
@@ -145,21 +139,21 @@ trait PullRequestsControllerBase extends ControllerBase {
// push // push
git.push.call git.push.call
val (commits, _) = getRequestCompareInfo(repository.owner, repository.name, pullreq.commitIdFrom, val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo) pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
commits.flatten.foreach { commit => commits.flatten.foreach { commit =>
if(!existsCommitId(repository.owner, repository.name, commit.id)){ if(!existsCommitId(owner, name, commit.id)){
insertCommitId(repository.owner, repository.name, commit.id) insertCommitId(owner, name, commit.id)
} }
} }
// notifications // notifications
Notifier().toNotify(repository, issueId, "merge"){ Notifier().toNotify(repository, issueId, "merge"){
Notifier.msgStatus(s"${baseUrl}/${repository.owner}/${repository.name}/pull/${issueId}") Notifier.msgStatus(s"${baseUrl}/${owner}/${name}/pull/${issueId}")
} }
redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}") redirect(s"/${owner}/${name}/pull/${issueId}")
} finally { } finally {
git.getRepository.close git.getRepository.close
@@ -167,6 +161,7 @@ trait PullRequestsControllerBase extends ControllerBase {
} }
} getOrElse NotFound } getOrElse NotFound
} }
}
}) })
/** /**
@@ -377,11 +372,10 @@ trait PullRequestsControllerBase extends ControllerBase {
val sessionKey = s"${owner}/${repoName}/pulls" val sessionKey = s"${owner}/${repoName}/pulls"
// retrieve search condition // retrieve search condition
val condition = if(request.getQueryString == null){ val condition = session.putAndGet(sessionKey,
session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition] if(request.hasQueryString) IssueSearchCondition(request)
} else IssueSearchCondition(request) else session.get(sessionKey).getOrElse(IssueSearchCondition()).asInstanceOf[IssueSearchCondition]
)
session.put(sessionKey, condition)
pulls.html.list( pulls.html.list(
searchIssue(condition, filterUser, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName), searchIssue(condition, filterUser, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),

View File

@@ -9,7 +9,6 @@ import org.scalatra.FlashMapSupport
import service.WebHookService.WebHookPayload import service.WebHookService.WebHookPayload
import util.JGitUtil.CommitInfo import util.JGitUtil.CommitInfo
import util.ControlUtil._ import util.ControlUtil._
import util.Implicits._
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
class RepositorySettingsController extends RepositorySettingsControllerBase class RepositorySettingsController extends RepositorySettingsControllerBase
@@ -123,8 +122,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
* Delete the web hook URL. * Delete the web hook URL.
*/ */
get("/:owner/:repository/settings/hooks/delete")(ownerOnly { repository => get("/:owner/:repository/settings/hooks/delete")(ownerOnly { repository =>
val url = params("url") deleteWebHookURL(repository.owner, repository.name, params("url"))
deleteWebHookURL(repository.owner, repository.name, url)
redirect(s"/${repository.owner}/${repository.name}/settings/hooks") redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
}) })
@@ -139,24 +137,19 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
.setMaxCount(3) .setMaxCount(3)
.call.iterator.asScala.map(new CommitInfo(_)) .call.iterator.asScala.map(new CommitInfo(_))
val payload = WebHookPayload( callWebHook(repository.owner, repository.name,
WebHookPayload(
git, git,
"refs/heads/" + repository.repository.defaultBranch, "refs/heads/" + repository.repository.defaultBranch,
repository, repository,
commits.toList, commits.toList,
getAccountByUserName(repository.owner).get) getAccountByUserName(repository.owner).get))
callWebHook(repository.owner, repository.name, payload)
flash += "info" -> "Test payload deployed!" flash += "info" -> "Test payload deployed!"
} }
redirect(s"/${repository.owner}/${repository.name}/settings/hooks") redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
}) })
// TODO Remove this action after web hook is completed.
post("/xxx/xxx/xxx/webhooktest"){
println(params("payload"))
}
/** /**
* Display the delete repository page. * Display the delete repository page.
*/ */
@@ -182,9 +175,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
*/ */
private def webHook: Constraint = new Constraint(){ private def webHook: Constraint = new Constraint(){
override def validate(name: String, value: String): Option[String] = override def validate(name: String, value: String): Option[String] =
defining(request.paths){ paths => getWebHookURLs(params("owner"), params("repository")).map(_.url).find(_ == value).map(_ => "URL had been registered already.")
getWebHookURLs(paths(1), paths(2)).map(_.url).find(_ == value).map(_ => "URL had been registered already.")
}
} }
/** /**
@@ -192,14 +183,12 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
*/ */
private def collaborator: Constraint = new Constraint(){ private def collaborator: Constraint = new Constraint(){
override def validate(name: String, value: String): Option[String] = override def validate(name: String, value: String): Option[String] =
defining(request.paths){ paths =>
getAccountByUserName(value) match { getAccountByUserName(value) match {
case None => Some("User does not exist.") case None => Some("User does not exist.")
case Some(x) if(x.userName == paths(1) || getCollaborators(paths(1), paths(2)).contains(x.userName)) case Some(x) if(x.userName == params("owner") || getCollaborators(params("owner"), params("repository")).contains(x.userName))
=> Some("User can access this repository already.") => Some("User can access this repository already.")
case _ => None case _ => None
} }
} }
}
} }

View File

@@ -23,7 +23,6 @@ trait SignInControllerBase extends ControllerBase { self: SystemSettingsService
} }
post("/signin", form){ form => post("/signin", form){ form =>
val settings = loadSystemSettings()
authenticate(loadSystemSettings(), form.userName, form.password) match { authenticate(loadSystemSettings(), form.userName, form.password) match {
case Some(account) => signin(account) case Some(account) => signin(account)
case None => redirect("/signin") case None => redirect("/signin")

View File

@@ -1,7 +1,7 @@
package util package util
import scala.util.matching.Regex import scala.util.matching.Regex
import javax.servlet.http.HttpServletRequest import javax.servlet.http.{HttpSession, HttpServletRequest}
/** /**
* Provides some usable implicit conversions. * Provides some usable implicit conversions.
@@ -44,7 +44,20 @@ object Implicits {
} }
implicit class RichRequest(request: HttpServletRequest){ implicit class RichRequest(request: HttpServletRequest){
def paths: Array[String] = request.getRequestURI.substring(request.getContextPath.length).split("/") def paths: Array[String] = request.getRequestURI.substring(request.getContextPath.length).split("/")
def hasQueryString: Boolean = request.getQueryString != null
def hasAttribute(name: String): Boolean = request.getAttribute(name) != null
}
implicit class RichSession(session: HttpSession){
def putAndGet[T](key: String, value: T): T = {
session.setAttribute(key, value)
value
}
} }
} }