mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-09 06:55:54 +01:00
(refs #464)Add authentication for plugin action
This commit is contained in:
@@ -91,8 +91,8 @@ object PluginSystem {
|
|||||||
case class PluginRepository(id: String, url: String)
|
case class PluginRepository(id: String, url: String)
|
||||||
case class GlobalMenu(label: String, url: String, icon: String, condition: Context => Boolean)
|
case class GlobalMenu(label: String, url: String, icon: String, condition: Context => Boolean)
|
||||||
case class RepositoryMenu(label: String, name: String, url: String, icon: String, condition: Context => Boolean)
|
case class RepositoryMenu(label: String, name: String, url: String, icon: String, condition: Context => Boolean)
|
||||||
case class Action(path: String, function: (HttpServletRequest, HttpServletResponse) => Any)
|
case class Action(path: String, security: String, function: (HttpServletRequest, HttpServletResponse) => Any)
|
||||||
case class RepositoryAction(path: String, function: (HttpServletRequest, HttpServletResponse, RepositoryInfo) => Any)
|
case class RepositoryAction(path: String, security: String, function: (HttpServletRequest, HttpServletResponse, RepositoryInfo) => Any)
|
||||||
case class Button(label: String, href: String)
|
case class Button(label: String, href: String)
|
||||||
case class JavaScript(filter: String => Boolean, script: String)
|
case class JavaScript(filter: String => Boolean, script: String)
|
||||||
|
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ class ScalaPlugin(val id: String, val version: String,
|
|||||||
globalMenuList += GlobalMenu(label, url, icon, condition)
|
globalMenuList += GlobalMenu(label, url, icon, condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
def addGlobalAction(path: String)(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = {
|
def addGlobalAction(path: String, security: String = "all")(function: (HttpServletRequest, HttpServletResponse) => Any): Unit = {
|
||||||
globalActionList += Action(path, function)
|
globalActionList += Action(path, security, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
def addRepositoryAction(path: String)(function: (HttpServletRequest, HttpServletResponse, RepositoryInfo) => Any): Unit = {
|
def addRepositoryAction(path: String, security: String = "all")(function: (HttpServletRequest, HttpServletResponse, RepositoryInfo) => Any): Unit = {
|
||||||
repositoryActionList += RepositoryAction(path, function)
|
repositoryActionList += RepositoryAction(path, security, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
def addJavaScript(filter: String => Boolean, script: String): Unit = {
|
def addJavaScript(filter: String => Boolean, script: String): Unit = {
|
||||||
|
|||||||
@@ -33,12 +33,19 @@ class PluginActionInvokeFilter extends Filter with SystemSettingsService with Re
|
|||||||
|
|
||||||
private def processGlobalAction(path: String, request: HttpServletRequest, response: HttpServletResponse): Boolean = {
|
private def processGlobalAction(path: String, request: HttpServletRequest, response: HttpServletResponse): Boolean = {
|
||||||
plugin.PluginSystem.globalActions.find(_.path == path).map { action =>
|
plugin.PluginSystem.globalActions.find(_.path == path).map { action =>
|
||||||
val result = action.function(request, response)
|
val loginAccount = request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]
|
||||||
val systemSettings = loadSystemSettings()
|
val systemSettings = loadSystemSettings()
|
||||||
|
implicit val context = app.Context(systemSettings, Option(loginAccount), request)
|
||||||
|
|
||||||
|
if(filterAction(action.security, context)){
|
||||||
|
val result = action.function(request, response)
|
||||||
result match {
|
result match {
|
||||||
case x: String => renderGlobalHtml(request, response, systemSettings, x)
|
case x: String => renderGlobalHtml(request, response, context, x)
|
||||||
case x: AnyRef => renderJson(request, response, x)
|
case x: AnyRef => renderJson(request, response, x)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// TODO NotFound or Error?
|
||||||
|
}
|
||||||
true
|
true
|
||||||
} getOrElse false
|
} getOrElse false
|
||||||
}
|
}
|
||||||
@@ -50,9 +57,14 @@ class PluginActionInvokeFilter extends Filter with SystemSettingsService with Re
|
|||||||
val owner = elements(1)
|
val owner = elements(1)
|
||||||
val name = elements(2)
|
val name = elements(2)
|
||||||
val remain = elements.drop(3).mkString("/", "/", "")
|
val remain = elements.drop(3).mkString("/", "/", "")
|
||||||
|
|
||||||
|
val loginAccount = request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]
|
||||||
val systemSettings = loadSystemSettings()
|
val systemSettings = loadSystemSettings()
|
||||||
|
implicit val context = app.Context(systemSettings, Option(loginAccount), request)
|
||||||
|
|
||||||
getRepository(owner, name, systemSettings.baseUrl(request)).flatMap { repository =>
|
getRepository(owner, name, systemSettings.baseUrl(request)).flatMap { repository =>
|
||||||
plugin.PluginSystem.repositoryActions.find(_.path == remain).map { action =>
|
plugin.PluginSystem.repositoryActions.find(_.path == remain).map { action =>
|
||||||
|
if(filterAction(action.security, context)){
|
||||||
val result = try {
|
val result = try {
|
||||||
PluginConnectionHolder.threadLocal.set(session.conn)
|
PluginConnectionHolder.threadLocal.set(session.conn)
|
||||||
action.function(request, response, repository)
|
action.function(request, response, repository)
|
||||||
@@ -60,30 +72,53 @@ class PluginActionInvokeFilter extends Filter with SystemSettingsService with Re
|
|||||||
PluginConnectionHolder.threadLocal.remove()
|
PluginConnectionHolder.threadLocal.remove()
|
||||||
}
|
}
|
||||||
result match {
|
result match {
|
||||||
case x: String => renderRepositoryHtml(request, response, systemSettings, repository, x)
|
case x: String => renderRepositoryHtml(request, response, context, repository, x)
|
||||||
case x: AnyRef => renderJson(request, response, x)
|
case x: AnyRef => renderJson(request, response, x)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// TODO NotFound or Error?
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
} getOrElse false
|
} getOrElse false
|
||||||
} else false
|
} else false
|
||||||
}
|
}
|
||||||
|
|
||||||
private def renderGlobalHtml(request: HttpServletRequest, response: HttpServletResponse,
|
private def filterAction(security: String, context: app.Context, repository: Option[RepositoryInfo] = None): Boolean = {
|
||||||
systemSettings: SystemSettings, body: String): Unit = {
|
if(repository.isDefined){
|
||||||
|
if(repository.get.repository.isPrivate){
|
||||||
|
security match {
|
||||||
|
case "owner" => context.loginAccount.isDefined && context.loginAccount.get.userName == repository.get.owner // TODO for group repository
|
||||||
|
case "member" => false // TODO owner or collaborator
|
||||||
|
case "admin" => context.loginAccount.isDefined && context.loginAccount.get.isAdmin
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
security match {
|
||||||
|
case "all" => true
|
||||||
|
case "login" => context.loginAccount.isDefined
|
||||||
|
case "owner" => context.loginAccount.isDefined && context.loginAccount.get.userName == repository.get.owner // TODO for group repository
|
||||||
|
case "member" => false // TODO owner or collaborator
|
||||||
|
case "admin" => context.loginAccount.isDefined && context.loginAccount.get.isAdmin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
security match {
|
||||||
|
case "all" => true
|
||||||
|
case "login" => context.loginAccount.isDefined
|
||||||
|
case "admin" => context.loginAccount.isDefined && context.loginAccount.get.isAdmin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def renderGlobalHtml(request: HttpServletRequest, response: HttpServletResponse, context: app.Context, body: String): Unit = {
|
||||||
response.setContentType("text/html; charset=UTF-8")
|
response.setContentType("text/html; charset=UTF-8")
|
||||||
val loginAccount = request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]
|
val html = _root_.html.main("GitBucket", None)(Html(body))(context)
|
||||||
implicit val context = app.Context(systemSettings, Option(loginAccount), request)
|
|
||||||
val html = _root_.html.main("GitBucket", None)(Html(body))
|
|
||||||
IOUtils.write(html.toString.getBytes("UTF-8"), response.getOutputStream)
|
IOUtils.write(html.toString.getBytes("UTF-8"), response.getOutputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def renderRepositoryHtml(request: HttpServletRequest, response: HttpServletResponse,
|
private def renderRepositoryHtml(request: HttpServletRequest, response: HttpServletResponse, context: app.Context, repository: RepositoryInfo, body: String): Unit = {
|
||||||
systemSettings: SystemSettings, repository: RepositoryInfo, body: String): Unit = {
|
|
||||||
response.setContentType("text/html; charset=UTF-8")
|
response.setContentType("text/html; charset=UTF-8")
|
||||||
val loginAccount = request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]
|
val html = _root_.html.main("GitBucket", None)(_root_.html.menu("", repository)(Html(body))(context))(context) // TODO specify active side menu
|
||||||
implicit val context = app.Context(systemSettings, Option(loginAccount), request)
|
|
||||||
val html = _root_.html.main("GitBucket", None)(_root_.html.menu("", repository)(Html(body))) // TODO specify active side menu
|
|
||||||
IOUtils.write(html.toString.getBytes("UTF-8"), response.getOutputStream)
|
IOUtils.write(html.toString.getBytes("UTF-8"), response.getOutputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user