Fix some Ajax URLs and Authenticators.

This commit is contained in:
takezoe
2013-07-03 01:45:38 +09:00
parent 00f921d330
commit 14187795fb
7 changed files with 108 additions and 84 deletions

View File

@@ -4,16 +4,16 @@ import jp.sf.amateras.scalatra.forms._
import service._
import IssuesService._
import util.UsersOnlyAuthenticator
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, ReadableUsersAuthenticator}
import org.scalatra.Ok
class IssuesController extends IssuesControllerBase
with IssuesService with RepositoryService with AccountService with LabelsService with MilestonesService
with UsersOnlyAuthenticator
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator
trait IssuesControllerBase extends ControllerBase {
self: IssuesService with RepositoryService with LabelsService with MilestonesService
with UsersOnlyAuthenticator =>
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator =>
case class IssueCreateForm(title: String, content: Option[String],
assignedUserName: Option[String], milestoneId: Option[Int], labelNames: Option[String])
@@ -40,19 +40,19 @@ trait IssuesControllerBase extends ControllerBase {
"content" -> trim(label("Comment", text(required)))
)(CommentForm.apply)
get("/:owner/:repository/issues"){
get("/:owner/:repository/issues")(referrersOnly {
searchIssues("all")
}
})
get("/:owner/:repository/issues/assigned/:userName"){
get("/:owner/:repository/issues/assigned/:userName")(referrersOnly {
searchIssues("assigned")
}
})
get("/:owner/:repository/issues/created_by/:userName"){
get("/:owner/:repository/issues/created_by/:userName")(referrersOnly {
searchIssues("created_by")
}
})
get("/:owner/:repository/issues/:id"){
get("/:owner/:repository/issues/:id")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val issueId = params("id")
@@ -67,10 +67,9 @@ trait IssuesControllerBase extends ControllerBase {
getLabels(owner, repository),
getRepository(owner, repository, baseUrl).get)
} getOrElse NotFound
}
})
// TODO requires users only and readable repository checking
get("/:owner/:repository/issues/new")( usersOnly {
get("/:owner/:repository/issues/new")( readableUsersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -83,8 +82,7 @@ trait IssuesControllerBase extends ControllerBase {
} getOrElse NotFound
})
// TODO requires users only and readable repository checking
post("/:owner/:repository/issues/new", issueCreateForm)( usersOnly { form =>
post("/:owner/:repository/issues/new", issueCreateForm)( readableUsersOnly { form =>
val owner = params("owner")
val repository = params("repository")
@@ -116,7 +114,7 @@ trait IssuesControllerBase extends ControllerBase {
}
// TODO requires users only and readable repository checking
post("/:owner/:repository/issue_comments/new", commentForm)( usersOnly { form =>
post("/:owner/:repository/issue_comments/new", commentForm)( referrersOnly { form =>
val owner = params("owner")
val repository = params("repository")
val action = params.get("action") filter { action =>
@@ -168,8 +166,7 @@ trait IssuesControllerBase extends ControllerBase {
} getOrElse NotFound
}
// TODO Authenticator
ajaxPost("/:owner/:repository/issues/:id/label/new"){
ajaxPost("/:owner/:repository/issues/:id/label/new")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val issueId = params("id").toInt
@@ -177,10 +174,9 @@ trait IssuesControllerBase extends ControllerBase {
registerIssueLabel(owner, repository, issueId, params("labelId").toInt)
issues.html.labellist(getIssueLabels(owner, repository, issueId))
}
})
// TODO Authenticator
ajaxPost("/:owner/:repository/issues/:id/label/delete"){
ajaxPost("/:owner/:repository/issues/:id/label/delete")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val issueId = params("id").toInt
@@ -188,9 +184,9 @@ trait IssuesControllerBase extends ControllerBase {
deleteIssueLabel(owner, repository, issueId, params("labelId").toInt)
issues.html.labellist(getIssueLabels(owner, repository, issueId))
}
})
ajaxPost("/:owner/:repository/issues/assign/:id"){
ajaxPost("/:owner/:repository/issues/:id/assign")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val issueId = params("id").toInt
@@ -201,9 +197,9 @@ trait IssuesControllerBase extends ControllerBase {
case Some(userName) => updateAssignedUserName(owner, repository, issueId, Some(userName))
}
Ok("updated")
}
})
ajaxPost("/:owner/:repository/issues/milestone/:id"){
ajaxPost("/:owner/:repository/issues/:id/milestone")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val issueId = params("id").toInt
@@ -214,7 +210,7 @@ trait IssuesControllerBase extends ControllerBase {
case Some(milestoneId) => updateMilestoneId(owner, repository, issueId, Some(milestoneId.toInt))
}
Ok("updated")
}
})
private def searchIssues(filter: String) = {
val owner = params("owner")

View File

@@ -2,13 +2,13 @@ package app
import jp.sf.amateras.scalatra.forms._
import service._
import util.WritableRepositoryAuthenticator
import util.CollaboratorsAuthenticator
class LabelsController extends LabelsControllerBase
with LabelsService with RepositoryService with AccountService with WritableRepositoryAuthenticator
with LabelsService with RepositoryService with AccountService with CollaboratorsAuthenticator
trait LabelsControllerBase extends ControllerBase {
self: LabelsService with RepositoryService with WritableRepositoryAuthenticator =>
self: LabelsService with RepositoryService with CollaboratorsAuthenticator =>
case class LabelForm(labelName: String, color: String)
@@ -22,7 +22,7 @@ trait LabelsControllerBase extends ControllerBase {
"editColor" -> trim(label("Color", text(required, color)))
)(LabelForm.apply)
post("/:owner/:repository/issues/label/new", newForm)(writableRepository { form =>
post("/:owner/:repository/issues/label/new", newForm)(collaboratorsOnly { form =>
val owner = params("owner")
val repository = params("repository")
@@ -31,7 +31,7 @@ trait LabelsControllerBase extends ControllerBase {
redirect("/%s/%s/issues".format(owner, repository))
})
ajaxGet("/:owner/:repository/issues/label/edit")(writableRepository {
ajaxGet("/:owner/:repository/issues/label/edit")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
@@ -39,7 +39,7 @@ trait LabelsControllerBase extends ControllerBase {
.map(issues.labels.html.editlist(getLabels(owner, repository), _)) getOrElse NotFound()
})
ajaxGet("/:owner/:repository/issues/label/:labelId/edit")(writableRepository {
ajaxGet("/:owner/:repository/issues/label/:labelId/edit")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val labelId = params("labelId").toInt
@@ -49,7 +49,7 @@ trait LabelsControllerBase extends ControllerBase {
} getOrElse NotFound()
})
ajaxPost("/:owner/:repository/issues/label/:labelId/edit", editForm)(writableRepository { form =>
ajaxPost("/:owner/:repository/issues/label/:labelId/edit", editForm)(collaboratorsOnly { form =>
val owner = params("owner")
val repository = params("repository")
val labelId = params("labelId").toInt
@@ -60,7 +60,7 @@ trait LabelsControllerBase extends ControllerBase {
} getOrElse NotFound()
})
ajaxGet("/:owner/:repository/issues/label/:labelId/delete")(writableRepository {
ajaxGet("/:owner/:repository/issues/label/:labelId/delete")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val labelId = params("labelId").toInt

View File

@@ -3,15 +3,15 @@ package app
import jp.sf.amateras.scalatra.forms._
import service._
import util.{WritableRepositoryAuthenticator, ReadableRepositoryAuthenticator, UsersOnlyAuthenticator}
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, UsersOnlyAuthenticator}
class MilestonesController extends MilestonesControllerBase
with MilestonesService with RepositoryService with AccountService
with ReadableRepositoryAuthenticator with WritableRepositoryAuthenticator
with ReferrerAuthenticator with CollaboratorsAuthenticator
trait MilestonesControllerBase extends ControllerBase {
self: MilestonesService with RepositoryService
with ReadableRepositoryAuthenticator with WritableRepositoryAuthenticator =>
with ReferrerAuthenticator with CollaboratorsAuthenticator =>
case class MilestoneForm(title: String, description: Option[String], dueDate: Option[java.util.Date])
@@ -21,7 +21,7 @@ trait MilestonesControllerBase extends ControllerBase {
"dueDate" -> trim(label("Due Date", optional(date())))
)(MilestoneForm.apply)
get("/:owner/:repository/issues/milestones")(readableRepository {
get("/:owner/:repository/issues/milestones")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val state = params.getOrElse("state", "open")
@@ -34,14 +34,14 @@ trait MilestonesControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/new")(writableRepository {
get("/:owner/:repository/issues/milestones/new")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
getRepository(owner, repository, baseUrl).map(issues.milestones.html.edit(None, _)) getOrElse NotFound
})
post("/:owner/:repository/issues/milestones/new", milestoneForm)(writableRepository { form =>
post("/:owner/:repository/issues/milestones/new", milestoneForm)(collaboratorsOnly { form =>
val owner = params("owner")
val repository = params("repository")
@@ -49,7 +49,7 @@ trait MilestonesControllerBase extends ControllerBase {
redirect("/%s/%s/issues/milestones".format(owner, repository))
})
get("/:owner/:repository/issues/milestones/:milestoneId/edit")(writableRepository {
get("/:owner/:repository/issues/milestones/:milestoneId/edit")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val milestoneId = params("milestoneId").toInt
@@ -58,7 +58,7 @@ trait MilestonesControllerBase extends ControllerBase {
issues.milestones.html.edit(getMilestone(owner, repository, milestoneId), _)) getOrElse NotFound
})
post("/:owner/:repository/issues/milestones/:milestoneId/edit", milestoneForm)(writableRepository { form =>
post("/:owner/:repository/issues/milestones/:milestoneId/edit", milestoneForm)(collaboratorsOnly { form =>
val owner = params("owner")
val repository = params("repository")
val milestoneId = params("milestoneId").toInt
@@ -69,7 +69,7 @@ trait MilestonesControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/:milestoneId/close")(writableRepository {
get("/:owner/:repository/issues/milestones/:milestoneId/close")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val milestoneId = params("milestoneId").toInt
@@ -80,7 +80,7 @@ trait MilestonesControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/:milestoneId/open")(writableRepository {
get("/:owner/:repository/issues/milestones/:milestoneId/open")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val milestoneId = params("milestoneId").toInt
@@ -91,7 +91,7 @@ trait MilestonesControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/issues/milestones/:milestoneId/delete")(writableRepository {
get("/:owner/:repository/issues/milestones/:milestoneId/delete")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val milestoneId = params("milestoneId").toInt

View File

@@ -2,7 +2,7 @@ package app
import util.Directory._
import util.Implicits._
import _root_.util.{ReadableRepositoryAuthenticator, JGitUtil, FileUtil}
import _root_.util.{ReferrerAuthenticator, JGitUtil, FileUtil}
import service._
import org.scalatra._
import java.io.File
@@ -12,18 +12,18 @@ import org.apache.commons.io.FileUtils
import org.eclipse.jgit.treewalk._
class RepositoryViewerController extends RepositoryViewerControllerBase
with RepositoryService with AccountService with ReadableRepositoryAuthenticator
with RepositoryService with AccountService with ReferrerAuthenticator
/**
* The repository viewer.
*/
trait RepositoryViewerControllerBase extends ControllerBase {
self: RepositoryService with AccountService with ReadableRepositoryAuthenticator =>
self: RepositoryService with AccountService with ReferrerAuthenticator =>
/**
* Returns converted HTML from Markdown for preview.
*/
post("/:owner/:repository/_preview")(readableRepository {
post("/:owner/:repository/_preview")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val content = params("content")
@@ -39,7 +39,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the file list of the repository root and the default branch.
*/
get("/:owner/:repository")(readableRepository {
get("/:owner/:repository")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -49,7 +49,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the file list of the repository root and the specified branch.
*/
get("/:owner/:repository/tree/:id")(readableRepository {
get("/:owner/:repository/tree/:id")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -59,7 +59,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the file list of the specified path and branch.
*/
get("/:owner/:repository/tree/:id/*")(readableRepository {
get("/:owner/:repository/tree/:id/*")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -69,7 +69,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the commit list of the specified branch.
*/
get("/:owner/:repository/commits/:branch")(readableRepository {
get("/:owner/:repository/commits/:branch")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val branchName = params("branch")
@@ -89,7 +89,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the commit list of the specified resource.
*/
get("/:owner/:repository/commits/:branch/*")(readableRepository {
get("/:owner/:repository/commits/:branch/*")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val branchName = params("branch")
@@ -111,7 +111,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays the file content of the specified branch or commit.
*/
get("/:owner/:repository/blob/:id/*")(readableRepository {
get("/:owner/:repository/blob/:id/*")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val id = params("id") // branch name or commit id
@@ -169,7 +169,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays details of the specified commit.
*/
get("/:owner/:repository/commit/:id")(readableRepository {
get("/:owner/:repository/commit/:id")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val id = params("id")
@@ -188,7 +188,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Displays tags.
*/
get("/:owner/:repository/tags")(readableRepository {
get("/:owner/:repository/tags")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -198,7 +198,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
/**
* Download repository contents as an archive.
*/
get("/:owner/:repository/archive/:name")(readableRepository {
get("/:owner/:repository/archive/:name")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val name = params("name")

View File

@@ -1,15 +1,15 @@
package app
import service._
import util.{WritableRepositoryAuthenticator, ReadableRepositoryAuthenticator, JGitUtil}
import util.{CollaboratorsAuthenticator, ReferrerAuthenticator, JGitUtil}
import util.Directory._
import jp.sf.amateras.scalatra.forms._
class WikiController extends WikiControllerBase
with WikiService with RepositoryService with AccountService with WritableRepositoryAuthenticator with ReadableRepositoryAuthenticator
with WikiService with RepositoryService with AccountService with CollaboratorsAuthenticator with ReferrerAuthenticator
trait WikiControllerBase extends ControllerBase {
self: WikiService with RepositoryService with WritableRepositoryAuthenticator with ReadableRepositoryAuthenticator =>
self: WikiService with RepositoryService with CollaboratorsAuthenticator with ReferrerAuthenticator =>
case class WikiPageEditForm(pageName: String, content: String, message: Option[String], currentPageName: String)
@@ -27,7 +27,7 @@ trait WikiControllerBase extends ControllerBase {
"currentPageName" -> trim(label("Current page name" , text(required)))
)(WikiPageEditForm.apply)
get("/:owner/:repository/wiki")(readableRepository {
get("/:owner/:repository/wiki")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -38,7 +38,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/:page")(readableRepository {
get("/:owner/:repository/wiki/:page")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val pageName = params("page")
@@ -50,7 +50,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/:page/_history")(readableRepository {
get("/:owner/:repository/wiki/:page/_history")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val page = params("page")
@@ -62,7 +62,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/:page/_compare/:commitId")(readableRepository {
get("/:owner/:repository/wiki/:page/_compare/:commitId")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val page = params("page")
@@ -75,7 +75,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/_compare/:commitId")(readableRepository {
get("/:owner/:repository/wiki/_compare/:commitId")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val commitId = params("commitId").split("\\.\\.\\.")
@@ -87,7 +87,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/:page/_edit")(writableRepository {
get("/:owner/:repository/wiki/:page/_edit")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val page = params("page")
@@ -96,7 +96,7 @@ trait WikiControllerBase extends ControllerBase {
wiki.html.edit(page, getWikiPage(owner, repository, page), _)) getOrElse NotFound
})
post("/:owner/:repository/wiki/_edit", editForm)(writableRepository { form =>
post("/:owner/:repository/wiki/_edit", editForm)(collaboratorsOnly { form =>
val owner = params("owner")
val repository = params("repository")
@@ -107,14 +107,14 @@ trait WikiControllerBase extends ControllerBase {
redirect("%s/%s/wiki/%s".format(owner, repository, form.pageName))
})
get("/:owner/:repository/wiki/_new")(writableRepository {
get("/:owner/:repository/wiki/_new")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
getRepository(owner, repository, baseUrl).map(wiki.html.edit("", None, _)) getOrElse NotFound
})
post("/:owner/:repository/wiki/_new", newForm)(writableRepository { form =>
post("/:owner/:repository/wiki/_new", newForm)(collaboratorsOnly { form =>
val owner = params("owner")
val repository = params("repository")
@@ -124,7 +124,7 @@ trait WikiControllerBase extends ControllerBase {
redirect("%s/%s/wiki/%s".format(owner, repository, form.pageName))
})
get("/:owner/:repository/wiki/:page/_delete")(writableRepository {
get("/:owner/:repository/wiki/:page/_delete")(collaboratorsOnly {
val owner = params("owner")
val repository = params("repository")
val page = params("page")
@@ -135,7 +135,7 @@ trait WikiControllerBase extends ControllerBase {
redirect("%s/%s/wiki".format(owner, repository))
})
get("/:owner/:repository/wiki/_pages")(readableRepository {
get("/:owner/:repository/wiki/_pages")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -144,7 +144,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/_history")(readableRepository {
get("/:owner/:repository/wiki/_history")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
@@ -155,7 +155,7 @@ trait WikiControllerBase extends ControllerBase {
} getOrElse NotFound
})
get("/:owner/:repository/wiki/_blob/*")(readableRepository {
get("/:owner/:repository/wiki/_blob/*")(referrersOnly {
val owner = params("owner")
val repository = params("repository")
val path = multiParams("splat").head

View File

@@ -60,9 +60,9 @@ trait AdminOnlyAuthenticator { self: ControllerBase =>
/**
* Allows only collaborators and administrators.
*/
trait WritableRepositoryAuthenticator { self: ControllerBase with RepositoryService =>
protected def writableRepository(action: => Any) = { authenticate(action) }
protected def writableRepository[T](action: T => Any) = (form: T) => authenticate({action(form)})
trait CollaboratorsAuthenticator { self: ControllerBase with RepositoryService =>
protected def collaboratorsOnly(action: => Any) = { authenticate(action) }
protected def collaboratorsOnly[T](action: T => Any) = (form: T) => authenticate({action(form)})
private def authenticate(action: => Any) = {
val paths = request.getRequestURI.split("/")
@@ -78,9 +78,9 @@ trait WritableRepositoryAuthenticator { self: ControllerBase with RepositoryServ
/**
* Allows only the repository owner and administrators.
*/
trait ReadableRepositoryAuthenticator { self: ControllerBase with RepositoryService =>
protected def readableRepository(action: => Any) = { authenticate(action) }
protected def readableRepository[T](action: T => Any) = (form: T) => authenticate({action(form)})
trait ReferrerAuthenticator { self: ControllerBase with RepositoryService =>
protected def referrersOnly(action: => Any) = { authenticate(action) }
protected def referrersOnly[T](action: T => Any) = (form: T) => authenticate({action(form)})
private def authenticate(action: => Any) = {
{
@@ -102,3 +102,27 @@ trait ReadableRepositoryAuthenticator { self: ControllerBase with RepositoryServ
}
}
}
/**
* Allows only signed in users which can access the repository.
*/
trait ReadableUsersAuthenticator { self: ControllerBase with RepositoryService =>
protected def readableUsersOnly(action: => Any) = { authenticate(action) }
protected def readableUsersOnly[T](action: T => Any) = (form: T) => authenticate({action(form)})
private def authenticate(action: => Any) = {
{
val paths = request.getRequestURI.split("/")
getRepository(paths(1), paths(2), baseUrl) match {
case None => NotFound()
case Some(repository) => context.loginAccount match {
case Some(x) if(x.isAdmin) => action
case Some(x) if(!repository.repository.isPrivate) => action
case Some(x) if(paths(1) == x.userName) => action
case Some(x) if(getCollaborators(paths(1), paths(2)).contains(x.userName)) => action
case _ => Unauthorized()
}
}
}
}
}

View File

@@ -145,9 +145,11 @@ $(function(){
$('a.assign').click(function(){
var userName = $(this).data('name');
$.post('@url(repository)/issues/assign/@issue.issueId', {
$.post('@url(repository)/issues/@issue.issueId/assign',
{
assignedUserName: userName
}, function(){
},
function(){
if(userName == ''){
$('#label-assigned').text('No one is assigned');
} else {
@@ -161,9 +163,11 @@ $(function(){
$('a.milestone').click(function(){
var title = $(this).text();
var milestoneId = $(this).data('id');
$.post('@url(repository)/issues/milestone/@issue.issueId', {
$.post('@url(repository)/issues/@issue.issueId/milestone',
{
milestoneId: milestoneId
}, function(){
},
function(){
if(milestoneId == ''){
$('#label-milestone').text('No milestone');
} else {