From 4c87bdd95957f41e2cc853e11a38cbd29b5d7c9c Mon Sep 17 00:00:00 2001 From: Herr Ritschwumm Date: Sat, 30 Jan 2016 08:05:00 +0100 Subject: [PATCH] refactor: make the settings alone responsible for ssh server location --- .../core/controller/ControllerBase.scala | 5 +--- .../controller/SystemSettingsController.scala | 15 ++++------ .../core/service/SystemSettingsService.scala | 18 +++++++++-- .../scala/gitbucket/core/ssh/NoShell.scala | 8 ++--- .../core/ssh/SshServerListener.scala | 30 +++++++++---------- 5 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/main/scala/gitbucket/core/controller/ControllerBase.scala b/src/main/scala/gitbucket/core/controller/ControllerBase.scala index a94c90a57..38d7ad92c 100644 --- a/src/main/scala/gitbucket/core/controller/ControllerBase.scala +++ b/src/main/scala/gitbucket/core/controller/ControllerBase.scala @@ -184,10 +184,7 @@ case class Context(settings: SystemSettingsService.SystemSettings, loginAccount: 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 1a4d1e4ff..413ef4cf7 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -68,16 +68,13 @@ trait SystemSettingsControllerBase extends ControllerBase { post("/admin/system", form)(adminOnly { form => saveSystemSettings(form) - if(form.ssh && SshServer.isActive && context.settings.sshPort != form.sshPort){ - SshServer.stop() - } - - if(form.ssh && !SshServer.isActive && form.baseUrl.isDefined){ - SshServer.start( - form.sshPortOrDefault, - form.baseUrl.get) - } else if(!form.ssh && SshServer.isActive){ + if (form.sshAddress != context.settings.sshAddress) { 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 35bda9330..082f05d1e 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 @@ object SystemSettingsService { 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 05975c28a..d1641872d 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 @@ class NoShell extends Factory[Command] with SystemSettingsService { override def start(env: Environment): Unit = { val user = env.getEnv.get("USER") - val port = loadSystemSettings().sshPortOrDefault val message = """ | Welcome to @@ -31,8 +31,8 @@ class NoShell extends Factory[Command] with SystemSettingsService { | | 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 060c4dfab..ccd21264c 100644 --- a/src/main/scala/gitbucket/core/ssh/SshServerListener.scala +++ b/src/main/scala/gitbucket/core/ssh/SshServerListener.scala @@ -5,7 +5,7 @@ import java.util.concurrent.atomic.AtomicBoolean 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 @@ object SshServer { 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 @@ class SshServerListener extends ServletContextListener with SystemSettingsServic 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() } }