diff --git a/src/main/scala/gitbucket/core/controller/ControllerBase.scala b/src/main/scala/gitbucket/core/controller/ControllerBase.scala index a94c90a..38d7ad9 100644 --- a/src/main/scala/gitbucket/core/controller/ControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/ControllerBase.scala @@ -184,10 +184,7 @@ val currentPath = request.getRequestURI.substring(request.getContextPath.length) val baseUrl = settings.baseUrl(request) val host = new java.net.URL(baseUrl).getHost - val repoBase = RepoBase( - baseUrl, - if (settings.ssh) Some(SshAddress(host, settings.sshPortOrDefault)) else None - ) + val repoBase = RepoBase(baseUrl, settings.sshAddress) val platform = request.getHeader("User-Agent") match { case null => null case agent if agent.contains("Mac") => "mac" diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index 1a4d1e4..413ef4c 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -68,16 +68,13 @@ post("/admin/system", form)(adminOnly { form => saveSystemSettings(form) - if(form.ssh && SshServer.isActive && context.settings.sshPort != form.sshPort){ + if (form.sshAddress != context.settings.sshAddress) { SshServer.stop() - } - - if(form.ssh && !SshServer.isActive && form.baseUrl.isDefined){ - SshServer.start( - form.sshPortOrDefault, - form.baseUrl.get) - } else if(!form.ssh && SshServer.isActive){ - SshServer.stop() + for { + sshAddress <- form.sshAddress + baseUrl <- form.baseUrl + } + SshServer.start(sshAddress, baseUrl) } flash += "info" -> "System settings has been updated." diff --git a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala index 35bda93..082f05d 100644 --- a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala +++ b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala @@ -1,6 +1,6 @@ package gitbucket.core.service -import gitbucket.core.util.{Directory, ControlUtil} +import gitbucket.core.util.{Directory, ControlUtil, SshAddress} import gitbucket.core.util.Implicits._ import Directory._ import ControlUtil._ @@ -133,7 +133,21 @@ ldapAuthentication: Boolean, ldap: Option[Ldap]){ def baseUrl(request: HttpServletRequest): String = baseUrl.fold(request.baseUrl)(_.stripSuffix("/")) - def sshPortOrDefault:Int = sshPort.getOrElse(DefaultSshPort) + + def sshAddress:Option[SshAddress] = + for { + host <- sshHostFromBaseUrl + if ssh + } + yield SshAddress(host, sshPort.getOrElse(DefaultSshPort)) + + // TODO host should be configured separately + private def sshHostFromBaseUrl:Option[String] = + for { + baseUrl <- baseUrl + m <- """^https?://([^:/]+)""".r.findFirstMatchIn(baseUrl) + } + yield m.group(1) } case class Ldap( diff --git a/src/main/scala/gitbucket/core/ssh/NoShell.scala b/src/main/scala/gitbucket/core/ssh/NoShell.scala index 05975c2..d164187 100644 --- a/src/main/scala/gitbucket/core/ssh/NoShell.scala +++ b/src/main/scala/gitbucket/core/ssh/NoShell.scala @@ -1,12 +1,13 @@ package gitbucket.core.ssh import gitbucket.core.service.SystemSettingsService +import gitbucket.core.util.SshAddress import org.apache.sshd.common.Factory import org.apache.sshd.server.{Environment, ExitCallback, Command} import java.io.{OutputStream, InputStream} import org.eclipse.jgit.lib.Constants -class NoShell extends Factory[Command] with SystemSettingsService { +class NoShell(sshAddress:SshAddress) extends Factory[Command] { override def create(): Command = new Command() { private var in: InputStream = null private var out: OutputStream = null @@ -15,7 +16,6 @@ override def start(env: Environment): Unit = { val user = env.getEnv.get("USER") - val port = loadSystemSettings().sshPortOrDefault val message = """ | Welcome to @@ -31,8 +31,8 @@ | | Please use: | - | git clone ssh://%s@GITBUCKET_HOST:%d/OWNER/REPOSITORY_NAME.git - """.stripMargin.format(user, port).replace("\n", "\r\n") + "\r\n" + | git clone ssh://%s@%s:%d/OWNER/REPOSITORY_NAME.git + """.stripMargin.format(user, sshAddress.host, sshAddress.port).replace("\n", "\r\n") + "\r\n" err.write(Constants.encode(message)) err.flush() in.close() diff --git a/src/main/scala/gitbucket/core/ssh/SshServerListener.scala b/src/main/scala/gitbucket/core/ssh/SshServerListener.scala index 060c4df..ccd2126 100644 --- a/src/main/scala/gitbucket/core/ssh/SshServerListener.scala +++ b/src/main/scala/gitbucket/core/ssh/SshServerListener.scala @@ -5,7 +5,7 @@ import javax.servlet.{ServletContextEvent, ServletContextListener} import gitbucket.core.service.SystemSettingsService -import gitbucket.core.util.Directory +import gitbucket.core.util.{Directory, SshAddress} import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider import org.slf4j.LoggerFactory @@ -14,20 +14,20 @@ private val server = org.apache.sshd.server.SshServer.setUpDefaultServer() private val active = new AtomicBoolean(false) - private def configure(port: Int, baseUrl: String) = { - server.setPort(port) + private def configure(sshAddress: SshAddress, baseUrl: String) = { + server.setPort(sshAddress.port) val provider = new SimpleGeneratorHostKeyProvider(new File(s"${Directory.GitBucketHome}/gitbucket.ser")) provider.setAlgorithm("RSA") provider.setOverwriteAllowed(false) server.setKeyPairProvider(provider) server.setPublickeyAuthenticator(new PublicKeyAuthenticator) server.setCommandFactory(new GitCommandFactory(baseUrl)) - server.setShellFactory(new NoShell) + server.setShellFactory(new NoShell(sshAddress)) } - def start(port: Int, baseUrl: String) = { + def start(sshAddress: SshAddress, baseUrl: String) = { if(active.compareAndSet(false, true)){ - configure(port, baseUrl) + configure(sshAddress, baseUrl) server.start() logger.info(s"Start SSH Server Listen on ${server.getPort}") } @@ -55,20 +55,18 @@ override def contextInitialized(sce: ServletContextEvent): Unit = { val settings = loadSystemSettings() - if(settings.ssh){ - settings.baseUrl match { - case None => - logger.error("Could not start SshServer because the baseUrl is not configured.") - case Some(baseUrl) => - SshServer.start(settings.sshPortOrDefault, baseUrl) - } + if (settings.sshAddress.isDefined && settings.baseUrl.isEmpty) { + logger.error("Could not start SshServer because the baseUrl is not configured.") } + for { + sshAddress <- settings.sshAddress + baseUrl <- settings.baseUrl + } + SshServer.start(sshAddress, baseUrl) } override def contextDestroyed(sce: ServletContextEvent): Unit = { - if(loadSystemSettings().ssh){ - SshServer.stop() - } + SshServer.stop() } }