mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-02 03:26:06 +01:00
Merge remote-tracking branch 'upstream/master' into pr-implemt-apis
This commit is contained in:
@@ -3,6 +3,8 @@ sudo: true
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk11
|
||||
- openjdk8
|
||||
- openjdk11
|
||||
script:
|
||||
- sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck test
|
||||
before_script:
|
||||
|
||||
24
build.sbt
24
build.sbt
@@ -5,7 +5,7 @@ val Organization = "io.github.gitbucket"
|
||||
val Name = "gitbucket"
|
||||
val GitBucketVersion = "4.30.0-SNAPSHOT"
|
||||
val ScalatraVersion = "2.6.3"
|
||||
val JettyVersion = "9.4.11.v20180605"
|
||||
val JettyVersion = "9.4.14.v20181114"
|
||||
val JgitVersion = "5.1.3.201810200350-r"
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
@@ -36,14 +36,14 @@ libraryDependencies ++= Seq(
|
||||
"org.scalatra" %% "scalatra" % ScalatraVersion,
|
||||
"org.scalatra" %% "scalatra-json" % ScalatraVersion,
|
||||
"org.scalatra" %% "scalatra-forms" % ScalatraVersion,
|
||||
"org.json4s" %% "json4s-jackson" % "3.5.4",
|
||||
"org.json4s" %% "json4s-jackson" % "3.6.2",
|
||||
"commons-io" % "commons-io" % "2.6",
|
||||
"io.github.gitbucket" % "solidbase" % "1.0.2",
|
||||
"io.github.gitbucket" % "solidbase" % "1.0.3",
|
||||
"io.github.gitbucket" % "markedj" % "1.0.15",
|
||||
"org.apache.commons" % "commons-compress" % "1.18",
|
||||
"org.apache.commons" % "commons-email" % "1.5",
|
||||
"org.apache.httpcomponents" % "httpclient" % "4.5.6",
|
||||
"org.apache.sshd" % "apache-sshd" % "1.7.0" exclude ("org.slf4j", "slf4j-jdk14"),
|
||||
"org.apache.sshd" % "apache-sshd" % "2.1.0" exclude ("org.slf4j", "slf4j-jdk14") exclude ("org.apache.sshd", "sshd-mina") exclude ("org.apache.sshd", "sshd-netty"),
|
||||
"org.apache.tika" % "tika-core" % "1.19.1",
|
||||
"com.github.takezoe" %% "blocking-slick-32" % "0.0.11",
|
||||
"com.novell.ldap" % "jldap" % "2009-10-07",
|
||||
@@ -51,13 +51,13 @@ libraryDependencies ++= Seq(
|
||||
"org.mariadb.jdbc" % "mariadb-java-client" % "2.3.0",
|
||||
"org.postgresql" % "postgresql" % "42.2.5",
|
||||
"ch.qos.logback" % "logback-classic" % "1.2.3",
|
||||
"com.zaxxer" % "HikariCP" % "2.7.9",
|
||||
"com.zaxxer" % "HikariCP" % "3.2.0",
|
||||
"com.typesafe" % "config" % "1.3.3",
|
||||
"com.typesafe.akka" %% "akka-actor" % "2.5.17",
|
||||
"com.typesafe.akka" %% "akka-actor" % "2.5.18",
|
||||
"fr.brouillard.oss.security.xhub" % "xhub4j-core" % "1.0.0",
|
||||
"com.github.bkromhout" % "java-diff-utils" % "2.1.1",
|
||||
"org.cache2k" % "cache2k-all" % "1.0.2.Final",
|
||||
"com.enragedginger" %% "akka-quartz-scheduler" % "1.7.0-akka-2.5.x" exclude ("c3p0", "c3p0"),
|
||||
"org.cache2k" % "cache2k-all" % "1.2.0.Final",
|
||||
"com.enragedginger" %% "akka-quartz-scheduler" % "1.7.0-akka-2.5.x" exclude ("c3p0", "c3p0") exclude ("com.zaxxer", "HikariCP-java6"),
|
||||
"net.coobird" % "thumbnailator" % "0.4.8",
|
||||
"com.github.zafarkhaja" % "java-semver" % "0.9.0",
|
||||
"com.nimbusds" % "oauth2-oidc-sdk" % "5.64.4",
|
||||
@@ -65,12 +65,12 @@ libraryDependencies ++= Seq(
|
||||
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
|
||||
"junit" % "junit" % "4.12" % "test",
|
||||
"org.scalatra" %% "scalatra-scalatest" % ScalatraVersion % "test",
|
||||
"org.mockito" % "mockito-core" % "2.23.0" % "test",
|
||||
"com.wix" % "wix-embedded-mysql" % "3.0.0" % "test",
|
||||
"ru.yandex.qatools.embed" % "postgresql-embedded" % "2.9" % "test",
|
||||
"org.mockito" % "mockito-core" % "2.23.4" % "test",
|
||||
"com.wix" % "wix-embedded-mysql" % "4.2.0" % "test",
|
||||
"ru.yandex.qatools.embed" % "postgresql-embedded" % "2.10" % "test",
|
||||
"net.i2p.crypto" % "eddsa" % "0.3.0",
|
||||
"is.tagomor.woothee" % "woothee-java" % "1.8.0",
|
||||
"org.ec4j.core" % "ec4j-core" % "0.0.1"
|
||||
"org.ec4j.core" % "ec4j-core" % "0.0.3"
|
||||
)
|
||||
|
||||
// Compiler settings
|
||||
|
||||
@@ -2,8 +2,9 @@ scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature")
|
||||
|
||||
addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.0")
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.3.15")
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.8")
|
||||
addSbtPlugin("org.scalatra.sbt" % "sbt-scalatra" % "1.0.1")
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
|
||||
addSbtPlugin("org.scalatra.sbt" % "sbt-scalatra" % "1.0.3")
|
||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2")
|
||||
addSbtCoursier
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-license-report" % "1.2.0")
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-license-report" % "1.2.0")
|
||||
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2")
|
||||
|
||||
@@ -421,7 +421,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
redirect(s"/${userName}/_application")
|
||||
})
|
||||
|
||||
get("/:userName/_hooks")(oneselfOnly {
|
||||
get("/:userName/_hooks")(managersOnly {
|
||||
val userName = params("userName")
|
||||
getAccountByUserName(userName).map { account =>
|
||||
gitbucket.core.account.html.hooks(account, getAccountWebHooks(account.userName), flash.get("info"))
|
||||
@@ -431,7 +431,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
/**
|
||||
* Display the account web hook edit page.
|
||||
*/
|
||||
get("/:userName/_hooks/new")(oneselfOnly {
|
||||
get("/:userName/_hooks/new")(managersOnly {
|
||||
val userName = params("userName")
|
||||
getAccountByUserName(userName).map { account =>
|
||||
val webhook = AccountWebHook(userName, "", WebHookContentType.FORM, None)
|
||||
@@ -442,7 +442,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
/**
|
||||
* Add the account web hook URL.
|
||||
*/
|
||||
post("/:userName/_hooks/new", accountWebHookForm(false))(oneselfOnly { form =>
|
||||
post("/:userName/_hooks/new", accountWebHookForm(false))(managersOnly { form =>
|
||||
val userName = params("userName")
|
||||
addAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
|
||||
flash += "info" -> s"Webhook ${form.url} created"
|
||||
@@ -452,7 +452,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
/**
|
||||
* Delete the account web hook URL.
|
||||
*/
|
||||
get("/:userName/_hooks/delete")(oneselfOnly {
|
||||
get("/:userName/_hooks/delete")(managersOnly {
|
||||
val userName = params("userName")
|
||||
deleteAccountWebHook(userName, params("url"))
|
||||
flash += "info" -> s"Webhook ${params("url")} deleted"
|
||||
@@ -462,7 +462,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
/**
|
||||
* Display the account web hook edit page.
|
||||
*/
|
||||
get("/:userName/_hooks/edit")(oneselfOnly {
|
||||
get("/:userName/_hooks/edit")(managersOnly {
|
||||
val userName = params("userName")
|
||||
getAccountByUserName(userName).flatMap { account =>
|
||||
getAccountWebHook(userName, params("url")).map {
|
||||
@@ -475,7 +475,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
/**
|
||||
* Update account web hook settings.
|
||||
*/
|
||||
post("/:userName/_hooks/edit", accountWebHookForm(true))(oneselfOnly { form =>
|
||||
post("/:userName/_hooks/edit", accountWebHookForm(true))(managersOnly { form =>
|
||||
val userName = params("userName")
|
||||
updateAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
|
||||
flash += "info" -> s"webhook ${form.url} updated"
|
||||
@@ -485,7 +485,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
||||
/**
|
||||
* Send the test request to registered account web hook URLs.
|
||||
*/
|
||||
ajaxPost("/:userName/_hooks/test")(oneselfOnly {
|
||||
ajaxPost("/:userName/_hooks/test")(managersOnly {
|
||||
// TODO Is it possible to merge with [[RepositorySettingsController.ajaxPost]]?
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent._
|
||||
|
||||
@@ -257,6 +257,7 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
"content" -> Markdown.toHtml(
|
||||
markdown = x.content getOrElse "No description given.",
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableAnchor = true,
|
||||
@@ -284,6 +285,7 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
"content" -> view.Markdown.toHtml(
|
||||
markdown = x.content,
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableAnchor = true,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package gitbucket.core.controller
|
||||
|
||||
import gitbucket.core.plugin.PluginRegistry
|
||||
import org.scalatra.MovedPermanently
|
||||
|
||||
class PreProcessController extends PreProcessControllerBase
|
||||
@@ -30,7 +31,10 @@ trait PreProcessControllerBase extends ControllerBase {
|
||||
*/
|
||||
get(!context.settings.allowAnonymousAccess, context.loginAccount.isEmpty) {
|
||||
if (!context.currentPath.startsWith("/assets") && !context.currentPath.startsWith("/signin") &&
|
||||
!context.currentPath.startsWith("/register") && !context.currentPath.endsWith("/info/refs")) {
|
||||
!context.currentPath.startsWith("/register") && !context.currentPath.endsWith("/info/refs") &&
|
||||
!PluginRegistry().getAnonymousAccessiblePaths().exists { path =>
|
||||
context.currentPath.startsWith(path)
|
||||
}) {
|
||||
Unauthorized()
|
||||
} else {
|
||||
pass()
|
||||
|
||||
@@ -512,10 +512,10 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
|
||||
private def mergeOptions = new ValueType[Seq[String]] {
|
||||
override def convert(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[String] = {
|
||||
params.get("mergeOptions").getOrElse(Nil)
|
||||
params.getOrElse("mergeOptions", Nil)
|
||||
}
|
||||
override def validate(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] = {
|
||||
val mergeOptions = params.get("mergeOptions").getOrElse(Nil)
|
||||
val mergeOptions = params.getOrElse("mergeOptions", Nil)
|
||||
if (mergeOptions.isEmpty) {
|
||||
Seq("mergeOptions" -> "At least one option must be enabled.")
|
||||
} else if (!mergeOptions.forall(x => Seq("merge-commit", "squash", "rebase").contains(x))) {
|
||||
|
||||
@@ -174,7 +174,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
helpers.renderMarkup(
|
||||
filePath = List(f),
|
||||
fileContent = params("content"),
|
||||
branch = "master",
|
||||
branch = repository.repository.defaultBranch,
|
||||
repository = repository,
|
||||
enableWikiLink = params("enableWikiLink").toBoolean,
|
||||
enableRefsLink = params("enableRefsLink").toBoolean,
|
||||
@@ -184,6 +184,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
helpers.markdown(
|
||||
markdown = params("content"),
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = params("enableWikiLink").toBoolean,
|
||||
enableRefsLink = params("enableRefsLink").toBoolean,
|
||||
enableLineBreaks = params("enableLineBreaks").toBoolean,
|
||||
@@ -679,6 +680,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
"content" -> view.Markdown.toHtml(
|
||||
markdown = x.content,
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableAnchor = true,
|
||||
@@ -943,18 +945,19 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
path: String
|
||||
) = {
|
||||
def archive(revision: String, archiveFormat: String, archive: ArchiveOutputStream)(
|
||||
entryCreator: (String, Long, Int) => ArchiveEntry
|
||||
entryCreator: (String, Long, java.util.Date, Int) => ArchiveEntry
|
||||
): Unit = {
|
||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
|
||||
val oid = git.getRepository.resolve(revision)
|
||||
val revCommit = JGitUtil.getRevCommitFromId(git, oid)
|
||||
val commit = JGitUtil.getRevCommitFromId(git, oid)
|
||||
val date = commit.getCommitterIdent.getWhen
|
||||
val sha1 = oid.getName()
|
||||
val repositorySuffix = (if (sha1.startsWith(revision)) sha1 else revision).replace('/', '-')
|
||||
val pathSuffix = if (path.isEmpty) "" else '-' + path.replace('/', '-')
|
||||
val baseName = repository.name + "-" + repositorySuffix + pathSuffix
|
||||
|
||||
using(new TreeWalk(git.getRepository)) { treeWalk =>
|
||||
treeWalk.addTree(revCommit.getTree)
|
||||
treeWalk.addTree(commit.getTree)
|
||||
treeWalk.setRecursive(true)
|
||||
if (!path.isEmpty) {
|
||||
treeWalk.setFilter(PathFilter.create(path))
|
||||
@@ -966,8 +969,8 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
else path.split("/").last + treeWalk.getPathString.substring(path.length)
|
||||
val size = JGitUtil.getFileSize(git, repository, treeWalk)
|
||||
val mode = treeWalk.getFileMode.getBits
|
||||
val entry: ArchiveEntry = entryCreator(entryPath, size, mode)
|
||||
JGitUtil.openFile(git, repository, revCommit.getTree, treeWalk.getPathString) { in =>
|
||||
val entry: ArchiveEntry = entryCreator(entryPath, size, date, mode)
|
||||
JGitUtil.openFile(git, repository, commit.getTree, treeWalk.getPathString) { in =>
|
||||
archive.putArchiveEntry(entry)
|
||||
IOUtils.copy(in, archive)
|
||||
archive.closeArchiveEntry()
|
||||
@@ -992,10 +995,11 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
contentType = "application/octet-stream"
|
||||
response.setBufferSize(1024 * 1024)
|
||||
using(new ZipArchiveOutputStream(response.getOutputStream)) { zip =>
|
||||
archive(revision, ".zip", zip) { (path, size, mode) =>
|
||||
archive(revision, ".zip", zip) { (path, size, date, mode) =>
|
||||
val entry = new ZipArchiveEntry(path)
|
||||
entry.setSize(size)
|
||||
entry.setUnixMode(mode)
|
||||
entry.setTime(date.getTime)
|
||||
entry
|
||||
}
|
||||
}
|
||||
@@ -1016,9 +1020,10 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR)
|
||||
tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU)
|
||||
tar.setAddPaxHeadersForNonAsciiNames(true)
|
||||
archive(revision, ".tar.gz", tar) { (path, size, mode) =>
|
||||
archive(revision, ".tar.gz", tar) { (path, size, date, mode) =>
|
||||
val entry = new TarArchiveEntry(path)
|
||||
entry.setSize(size)
|
||||
entry.setModTime(date)
|
||||
entry.setMode(mode)
|
||||
entry
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||
import gitbucket.core.util.SyntaxSugars._
|
||||
import io.github.gitbucket.solidbase.model.Version
|
||||
import org.apache.sshd.server.Command
|
||||
import org.apache.sshd.server.command.Command
|
||||
import play.twirl.api.Html
|
||||
|
||||
/**
|
||||
@@ -47,6 +47,20 @@ abstract class Plugin {
|
||||
settings: SystemSettings
|
||||
): Seq[(String, ControllerBase)] = Nil
|
||||
|
||||
/**
|
||||
* Override to declare this plug-in provides anonymous accessible paths.
|
||||
*/
|
||||
val anonymousAccessiblePaths: Seq[String] = Nil
|
||||
|
||||
/**
|
||||
* Override to declare this plug-in provides anonymous accessible paths.
|
||||
*/
|
||||
def anonymousAccessiblePaths(
|
||||
registry: PluginRegistry,
|
||||
context: ServletContext,
|
||||
settings: SystemSettings
|
||||
): Seq[String] = Nil
|
||||
|
||||
/**
|
||||
* Override to declare this plug-in provides JavaScript.
|
||||
*/
|
||||
@@ -333,6 +347,10 @@ abstract class Plugin {
|
||||
case (path, controller) =>
|
||||
registry.addController(path, controller)
|
||||
}
|
||||
(anonymousAccessiblePaths ++ anonymousAccessiblePaths(registry, context, settings)).foreach {
|
||||
case (path) =>
|
||||
registry.addAnonymousAccessiblePath(path)
|
||||
}
|
||||
(javaScripts ++ javaScripts(registry, context, settings)).foreach {
|
||||
case (path, script) =>
|
||||
registry.addJavaScript(path, script)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package gitbucket.core.plugin
|
||||
|
||||
import java.io.{File, FilenameFilter, InputStream}
|
||||
import java.io.{File, FilenameFilter}
|
||||
import java.net.URLClassLoader
|
||||
import java.nio.file.{Files, Paths, StandardWatchEventKinds}
|
||||
import java.util.Base64
|
||||
@@ -15,7 +15,6 @@ import gitbucket.core.service.ProtectedBranchService.ProtectedBranchReceiveHook
|
||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||
import gitbucket.core.service.SystemSettingsService
|
||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||
import gitbucket.core.util.SyntaxSugars._
|
||||
import gitbucket.core.util.DatabaseConfig
|
||||
import gitbucket.core.util.Directory._
|
||||
import gitbucket.core.util.HttpClientUtil._
|
||||
@@ -24,7 +23,7 @@ import io.github.gitbucket.solidbase.manager.JDBCVersionManager
|
||||
import io.github.gitbucket.solidbase.model.Module
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.apache.http.client.methods.HttpGet
|
||||
import org.apache.sshd.server.Command
|
||||
import org.apache.sshd.server.command.Command
|
||||
import org.slf4j.LoggerFactory
|
||||
import play.twirl.api.Html
|
||||
|
||||
@@ -35,6 +34,7 @@ class PluginRegistry {
|
||||
private val plugins = new ConcurrentLinkedQueue[PluginInfo]
|
||||
private val javaScripts = new ConcurrentLinkedQueue[(String, String)]
|
||||
private val controllers = new ConcurrentLinkedQueue[(ControllerBase, String)]
|
||||
private val anonymousAccessiblePaths = new ConcurrentLinkedQueue[String]
|
||||
private val images = new ConcurrentHashMap[String, String]
|
||||
private val renderers = new ConcurrentHashMap[String, Renderer]
|
||||
renderers.put("md", MarkdownRenderer)
|
||||
@@ -70,25 +70,16 @@ class PluginRegistry {
|
||||
images.put(id, encoded)
|
||||
}
|
||||
|
||||
@deprecated("Use addImage(id: String, bytes: Array[Byte]) instead", "3.4.0")
|
||||
def addImage(id: String, in: InputStream): Unit = {
|
||||
val bytes = using(in) { in =>
|
||||
val bytes = new Array[Byte](in.available)
|
||||
in.read(bytes)
|
||||
bytes
|
||||
}
|
||||
addImage(id, bytes)
|
||||
}
|
||||
|
||||
def getImage(id: String): String = images.get(id)
|
||||
|
||||
def addController(path: String, controller: ControllerBase): Unit = controllers.add((controller, path))
|
||||
|
||||
@deprecated("Use addController(path: String, controller: ControllerBase) instead", "3.4.0")
|
||||
def addController(controller: ControllerBase, path: String): Unit = addController(path, controller)
|
||||
|
||||
def getControllers(): Seq[(ControllerBase, String)] = controllers.asScala.toSeq
|
||||
|
||||
def addAnonymousAccessiblePath(path: String): Unit = anonymousAccessiblePaths.add(path)
|
||||
|
||||
def getAnonymousAccessiblePaths(): Seq[String] = anonymousAccessiblePaths.asScala.toSeq
|
||||
|
||||
def addJavaScript(path: String, script: String): Unit =
|
||||
javaScripts.add((path, script)) //javaScripts += ((path, script))
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ object MarkdownRenderer extends Renderer {
|
||||
Markdown.toHtml(
|
||||
markdown = fileContent,
|
||||
repository = repository,
|
||||
branch = branch,
|
||||
enableWikiLink = enableWikiLink,
|
||||
enableRefsLink = enableRefsLink,
|
||||
enableAnchor = enableAnchor,
|
||||
|
||||
@@ -6,7 +6,7 @@ import gitbucket.core.service.{AccountService, DeployKeyService, RepositoryServi
|
||||
import gitbucket.core.servlet.{CommitLogHook, Database}
|
||||
import gitbucket.core.util.{SyntaxSugars, Directory}
|
||||
import org.apache.sshd.server.{Environment, ExitCallback, SessionAware}
|
||||
import org.apache.sshd.server.{Command, CommandFactory}
|
||||
import org.apache.sshd.server.command.{Command, CommandFactory}
|
||||
import org.apache.sshd.server.session.ServerSession
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.{File, InputStream, OutputStream}
|
||||
@@ -16,7 +16,7 @@ import org.eclipse.jgit.api.Git
|
||||
import Directory._
|
||||
import gitbucket.core.ssh.PublicKeyAuthenticator.AuthType
|
||||
import org.eclipse.jgit.transport.{ReceivePack, UploadPack}
|
||||
import org.apache.sshd.server.scp.UnknownCommand
|
||||
import org.apache.sshd.server.shell.UnknownCommand
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException
|
||||
|
||||
object GitCommand {
|
||||
|
||||
@@ -3,7 +3,7 @@ package gitbucket.core.ssh
|
||||
import gitbucket.core.service.SystemSettingsService.SshAddress
|
||||
import org.apache.sshd.common.Factory
|
||||
import org.apache.sshd.server.{Environment, ExitCallback}
|
||||
import org.apache.sshd.server.Command
|
||||
import org.apache.sshd.server.command.Command
|
||||
import java.io.{OutputStream, InputStream}
|
||||
import org.eclipse.jgit.lib.Constants
|
||||
|
||||
|
||||
@@ -161,6 +161,8 @@ trait GroupManagerAuthenticator { self: ControllerBase with AccountService =>
|
||||
|
||||
private def authenticate(action: => Any) = {
|
||||
context.loginAccount match {
|
||||
case Some(x) if x.isAdmin => action
|
||||
case Some(x) if x.userName == request.paths(0) => action
|
||||
case Some(x) if (getGroupMembers(request.paths(0)).exists { member =>
|
||||
member.userName == x.userName && member.isManager
|
||||
}) =>
|
||||
|
||||
@@ -65,7 +65,7 @@ object SyntaxSugars {
|
||||
implicit class HeadValueAccessibleMap(map: Map[String, Seq[String]]) {
|
||||
def value(key: String): String = map(key).head
|
||||
def optionValue(key: String): Option[String] = map.get(key).flatMap(_.headOption)
|
||||
def values(key: String): Seq[String] = map.get(key).getOrElse(Seq.empty)
|
||||
def values(key: String): Seq[String] = map.getOrElse(key, Seq.empty)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ object Markdown {
|
||||
* Converts Markdown of Wiki pages to HTML.
|
||||
*
|
||||
* @param repository the repository which contains the markdown
|
||||
* @param branch the target branch
|
||||
* @param enableWikiLink if true then wiki style link is available in markdown
|
||||
* @param enableRefsLink if true then issue reference (e.g. #123) is rendered as link
|
||||
* @param enableAnchor if true then anchor for headline is generated
|
||||
@@ -27,6 +28,7 @@ object Markdown {
|
||||
def toHtml(
|
||||
markdown: String,
|
||||
repository: RepositoryService.RepositoryInfo,
|
||||
branch: String,
|
||||
enableWikiLink: Boolean,
|
||||
enableRefsLink: Boolean,
|
||||
enableAnchor: Boolean,
|
||||
@@ -45,6 +47,7 @@ object Markdown {
|
||||
val renderer = new GitBucketMarkedRenderer(
|
||||
options,
|
||||
repository,
|
||||
branch,
|
||||
enableWikiLink,
|
||||
enableRefsLink,
|
||||
enableAnchor,
|
||||
@@ -62,6 +65,7 @@ object Markdown {
|
||||
class GitBucketMarkedRenderer(
|
||||
options: Options,
|
||||
repository: RepositoryService.RepositoryInfo,
|
||||
branch: String,
|
||||
enableWikiLink: Boolean,
|
||||
enableRefsLink: Boolean,
|
||||
enableAnchor: Boolean,
|
||||
@@ -131,11 +135,11 @@ object Markdown {
|
||||
}
|
||||
|
||||
override def link(href: String, title: String, text: String): String = {
|
||||
super.link(fixUrl(href, false), title, text)
|
||||
super.link(fixUrl(href, branch, false), title, text)
|
||||
}
|
||||
|
||||
override def image(href: String, title: String, text: String): String = {
|
||||
super.image(fixUrl(href, true), title, text)
|
||||
super.image(fixUrl(href, branch, true), title, text)
|
||||
}
|
||||
|
||||
override def nolink(text: String): String = {
|
||||
@@ -162,7 +166,7 @@ object Markdown {
|
||||
}
|
||||
}
|
||||
|
||||
private def fixUrl(url: String, isImage: Boolean = false): String = {
|
||||
private def fixUrl(url: String, branch: String, isImage: Boolean = false): String = {
|
||||
lazy val urlWithRawParam: String = url + (if (isImage && !url.endsWith("?raw=true")) "?raw=true" else "")
|
||||
|
||||
if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:") || url.startsWith("/")) {
|
||||
@@ -172,13 +176,7 @@ object Markdown {
|
||||
} else if (!enableWikiLink) {
|
||||
if (context.currentPath.contains("/blob/")) {
|
||||
urlWithRawParam
|
||||
} else if (context.currentPath.contains("/tree/")) {
|
||||
val paths = context.currentPath.split("/")
|
||||
val branch = if (paths.length > 3) paths.drop(4).mkString("/") else repository.repository.defaultBranch
|
||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + urlWithRawParam
|
||||
} else {
|
||||
val paths = context.currentPath.split("/")
|
||||
val branch = if (paths.length > 3) paths.last else repository.repository.defaultBranch
|
||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + urlWithRawParam
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -102,6 +102,7 @@ object helpers extends AvatarImageProvider with LinkConverter with RequestCache
|
||||
def markdown(
|
||||
markdown: String,
|
||||
repository: RepositoryService.RepositoryInfo,
|
||||
branch: String,
|
||||
enableWikiLink: Boolean,
|
||||
enableRefsLink: Boolean,
|
||||
enableLineBreaks: Boolean,
|
||||
@@ -114,6 +115,7 @@ object helpers extends AvatarImageProvider with LinkConverter with RequestCache
|
||||
Markdown.toHtml(
|
||||
markdown = markdown,
|
||||
repository = repository,
|
||||
branch = branch,
|
||||
enableWikiLink = enableWikiLink,
|
||||
enableRefsLink = enableRefsLink,
|
||||
enableAnchor = enableAnchor,
|
||||
|
||||
@@ -22,12 +22,13 @@
|
||||
</div>
|
||||
<div class="commit-commentContent-@comment.commentId">
|
||||
@helpers.markdown(
|
||||
markdown = comment.content,
|
||||
repository = repository,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
markdown = comment.content,
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = hasWritePermission
|
||||
)
|
||||
</div>
|
||||
|
||||
@@ -32,12 +32,13 @@
|
||||
</div>
|
||||
<div class="panel-body markdown-body" id="commentContent-@comment.commentId">
|
||||
@helpers.markdown(
|
||||
markdown = comment.content,
|
||||
repository = repository,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
markdown = comment.content,
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = isManageable
|
||||
)
|
||||
</div>
|
||||
@@ -57,12 +58,13 @@
|
||||
</div>
|
||||
<div class="panel-body markdown-body" id="issueContent">
|
||||
@helpers.markdown(
|
||||
markdown = issue.get.content getOrElse "No description provided.",
|
||||
repository = repository,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
markdown = issue.get.content getOrElse "No description provided.",
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = isManageable
|
||||
)
|
||||
</div>
|
||||
@@ -268,12 +270,13 @@
|
||||
</div>
|
||||
<div class="panel-body markdown-body commit-commentContent-@comment.commentId">
|
||||
@helpers.markdown(
|
||||
markdown = comment.content,
|
||||
repository = repository,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
markdown = comment.content,
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
enableTaskList = true,
|
||||
hasWritePermission = isManageable
|
||||
)
|
||||
</div>
|
||||
|
||||
@@ -76,13 +76,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if(milestone.description.isDefined){
|
||||
@milestone.description.map { description =>
|
||||
<div class="milestone-description markdown-body">
|
||||
@helpers.markdown(
|
||||
markdown = milestone.description.get,
|
||||
repository = repository,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = false,
|
||||
markdown = description,
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = false,
|
||||
enableLineBreaks = true
|
||||
)
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,14 @@
|
||||
</div>
|
||||
<div>
|
||||
<hr>
|
||||
@status.conflictMessage.map { message => @helpers.markdown(message, originRepository, false, true, false) }
|
||||
@status.conflictMessage.map { message => @helpers.markdown(
|
||||
markdown = message,
|
||||
repository = originRepository,
|
||||
branch = originRepository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = false
|
||||
) }
|
||||
</div>
|
||||
} else {
|
||||
@if(status.branchIsOutOfDate){
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
@helpers.markdown(
|
||||
markdown = release.content getOrElse "No description provided.",
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
@helpers.markdown(
|
||||
markdown = release.content getOrElse "No description provided.",
|
||||
repository = repository,
|
||||
branch = repository.repository.defaultBranch,
|
||||
enableWikiLink = false,
|
||||
enableRefsLink = true,
|
||||
enableLineBreaks = true,
|
||||
|
||||
@@ -181,7 +181,7 @@ $(function(){
|
||||
error:function (e) {
|
||||
if(e) {
|
||||
console.log(e.responseText, e);
|
||||
alert("request error ( http status " + e.status + " error on gitbugket or browser to gitbucket. show details on your javascript console )");
|
||||
alert("request error ( http status " + e.status + " error on gitbucket or browser to gitbucket. show details on your javascript console )");
|
||||
}else{
|
||||
alert("unknown javascript error (please report to gitbucket team)");
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
@if(isEditable){
|
||||
<a href="@helpers.url(repository)/wiki/_Sidebar/_edit" style="text-decoration: none;"><span class="octicon octicon-pencil pull-right"></span></a>
|
||||
}
|
||||
@helpers.markdown(sidebarPage.content, repository, true, false, false, false, pages)
|
||||
@helpers.markdown(sidebarPage.content, repository, "master", true, false, false, false, pages)
|
||||
</div>
|
||||
}.getOrElse{
|
||||
@if(isEditable){
|
||||
@@ -85,6 +85,7 @@
|
||||
@helpers.markdown(
|
||||
markdown = page.content,
|
||||
repository = repository,
|
||||
branch = "master",
|
||||
enableWikiLink = true,
|
||||
enableRefsLink = false,
|
||||
enableLineBreaks = false,
|
||||
@@ -98,7 +99,16 @@
|
||||
@if(isEditable){
|
||||
<a href="@helpers.url(repository)/wiki/_Footer/_edit" style="text-decoration: none;"><span class="octicon octicon-pencil pull-right"></span></a>
|
||||
}
|
||||
@helpers.markdown(footerPage.content, repository, true, false, false, false, pages)
|
||||
@helpers.markdown(
|
||||
markdown = footerPage.content,
|
||||
repository = repository,
|
||||
branch = "master",
|
||||
enableWikiLink = true,
|
||||
enableRefsLink = false,
|
||||
enableLineBreaks = false,
|
||||
enableAnchor = false,
|
||||
pages = pages
|
||||
)
|
||||
</div>
|
||||
}.getOrElse{
|
||||
@if(isEditable){
|
||||
|
||||
@@ -33,7 +33,6 @@ class GitBucketCoreModuleSpec extends FunSuite {
|
||||
.withPort(3306)
|
||||
.withUser("sa", "sa")
|
||||
.withCharset(Charset.UTF8)
|
||||
.withServerVariable("log_syslog", 0)
|
||||
.withServerVariable("bind-address", "127.0.0.1")
|
||||
.build()
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package gitbucket.core.service
|
||||
import gitbucket.core.model._
|
||||
import org.scalatest.FunSuite
|
||||
import gitbucket.core.model.Profile._
|
||||
import gitbucket.core.model.Profile.profile._
|
||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||
|
||||
class AccessTokenServiceSpec extends FunSuite with ServiceSpecBase {
|
||||
@@ -53,6 +52,7 @@ class AccessTokenServiceSpec extends FunSuite with ServiceSpecBase {
|
||||
val (id, token) = AccessTokenService.generateAccessToken("root", "note")
|
||||
assert(AccessTokenService.getAccountByAccessToken(token) match {
|
||||
case Some(user) => user.userName == "root"
|
||||
case _ => fail()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,7 @@ class AccessTokenServiceSpec extends FunSuite with ServiceSpecBase {
|
||||
|
||||
assert(AccessTokenService.getAccountByAccessToken(token) match {
|
||||
case Some(user) => user.userName == "user3"
|
||||
case _ => fail()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package gitbucket.core.ssh
|
||||
|
||||
import org.apache.sshd.server.scp.UnknownCommand
|
||||
import org.apache.sshd.server.shell.UnknownCommand
|
||||
import org.scalatest.FunSpec
|
||||
|
||||
class GitCommandFactorySpec extends FunSpec {
|
||||
|
||||
Reference in New Issue
Block a user