diff --git a/src/main/scala/app/SystemSettingsController.scala b/src/main/scala/app/SystemSettingsController.scala index c6f56fe..1d3718a 100644 --- a/src/main/scala/app/SystemSettingsController.scala +++ b/src/main/scala/app/SystemSettingsController.scala @@ -4,6 +4,7 @@ import SystemSettingsService._ import util.AdminAuthenticator import jp.sf.amateras.scalatra.forms._ +import ssh.SshServer class SystemSettingsController extends SystemSettingsControllerBase with SystemSettingsService with AccountService with AdminAuthenticator @@ -16,6 +17,8 @@ "allowAccountRegistration" -> trim(label("Account registration", boolean())), "gravatar" -> trim(label("Gravatar", boolean())), "notification" -> trim(label("Notification", boolean())), + "ssh" -> trim(label("SSH access", boolean())), + "sshPort" -> trim(label("SSH port", optional(number()))), "smtp" -> optionalIfNotChecked("notification", mapping( "host" -> trim(label("SMTP Host", text(required))), "port" -> trim(label("SMTP Port", optional(number()))), @@ -47,6 +50,13 @@ post("/admin/system", form)(adminOnly { form => saveSystemSettings(form) + + if(form.ssh && !SshServer.isActive){ + SshServer.start(request.getServletContext, form.sshPort.getOrElse(SystemSettingsService.DefaultSshPort)) + } else if(!form.ssh && SshServer.isActive){ + SshServer.stop() + } + flash += "info" -> "System settings has been updated." redirect("/admin/system") }) diff --git a/src/main/scala/service/SystemSettingsService.scala b/src/main/scala/service/SystemSettingsService.scala index f15bd37..51e468e 100644 --- a/src/main/scala/service/SystemSettingsService.scala +++ b/src/main/scala/service/SystemSettingsService.scala @@ -19,6 +19,8 @@ props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString) props.setProperty(Gravatar, settings.gravatar.toString) props.setProperty(Notification, settings.notification.toString) + props.setProperty(Ssh, settings.ssh.toString) + settings.sshPort.foreach(x => props.setProperty(SshPort, x.toString)) if(settings.notification) { settings.smtp.foreach { smtp => props.setProperty(SmtpHost, smtp.host) @@ -60,6 +62,8 @@ getValue(props, AllowAccountRegistration, false), getValue(props, Gravatar, true), getValue(props, Notification, false), + getValue(props, Ssh, false), + getOptionValue(props, SshPort, Some(DefaultSshPort)), if(getValue(props, Notification, false)){ Some(Smtp( getValue(props, SmtpHost, ""), @@ -102,6 +106,8 @@ allowAccountRegistration: Boolean, gravatar: Boolean, notification: Boolean, + ssh: Boolean, + sshPort: Option[Int], smtp: Option[Smtp], ldapAuthentication: Boolean, ldap: Option[Ldap]) @@ -127,6 +133,7 @@ fromAddress: Option[String], fromName: Option[String]) + val DefaultSshPort = 29418 val DefaultSmtpPort = 25 val DefaultLdapPort = 389 @@ -134,6 +141,8 @@ private val AllowAccountRegistration = "allow_account_registration" private val Gravatar = "gravatar" private val Notification = "notification" + private val Ssh = "ssh" + private val SshPort = "ssh.port" private val SmtpHost = "smtp.host" private val SmtpPort = "smtp.port" private val SmtpUser = "smtp.user" diff --git a/src/main/scala/ssh/GitCommand.scala b/src/main/scala/ssh/GitCommand.scala index 909e92b..95583fa 100644 --- a/src/main/scala/ssh/GitCommand.scala +++ b/src/main/scala/ssh/GitCommand.scala @@ -82,7 +82,7 @@ } } -class GitUploadPack(override val command: String) extends GitCommand(command: String) { +class GitUploadPack(context: ServletContext, override val command: String) extends GitCommand(command: String) { override protected def runTask(user: String): Unit = { using(Git.open(getRepositoryDir(owner, repositoryName))) { @@ -119,7 +119,7 @@ override def createCommand(command: String): Command = { logger.debug(s"command: $command") command match { - case GitCommand.CommandRegex("upload", owner, repoName) => new GitUploadPack(command) + case GitCommand.CommandRegex("upload", owner, repoName) => new GitUploadPack(context, command) case GitCommand.CommandRegex("receive", owner, repoName) => new GitReceivePack(context, command) case _ => new UnknownCommand(command) } diff --git a/src/main/scala/ssh/SshServerListener.scala b/src/main/scala/ssh/SshServerListener.scala index 79434b8..a23ef43 100644 --- a/src/main/scala/ssh/SshServerListener.scala +++ b/src/main/scala/ssh/SshServerListener.scala @@ -4,36 +4,36 @@ import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider import org.slf4j.LoggerFactory import util.Directory - +import service.SystemSettingsService +import java.util.concurrent.atomic.AtomicBoolean object SshServer { private val logger = LoggerFactory.getLogger(SshServer.getClass) - - val DEFAULT_PORT: Int = 29418 - // TODO read from config - val SSH_SERVICE_ENABLE = true // TODO read from config - private val server = org.apache.sshd.SshServer.setUpDefaultServer() + private val active = new AtomicBoolean(false); - private def configure(context: ServletContext) = { - server.setPort(DEFAULT_PORT) // TODO read from config + private def configure(context: ServletContext, port: Int) = { + server.setPort(port) server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(s"${Directory.GitBucketHome}/gitbucket.ser")) server.setPublickeyAuthenticator(new PublicKeyAuthenticator(context)) server.setCommandFactory(new GitCommandFactory(context)) } - def start(context: ServletContext) = this.synchronized { - if (SSH_SERVICE_ENABLE) { - - configure(context) + def start(context: ServletContext, port: Int) = { + if(active.compareAndSet(false, true)){ + configure(context, port) server.start() logger.info(s"Start SSH Server Listen on ${server.getPort}") } } def stop() = { - server.stop(true) + if(active.compareAndSet(true, false)){ + server.stop(true) + } } + + def isActive = active.get } /* @@ -41,16 +41,20 @@ * * How to use: * git clone ssh://username@host_or_ip:29418/owner/repository_name.git - * */ -class SshServerListener extends ServletContextListener { +class SshServerListener extends ServletContextListener with SystemSettingsService { override def contextInitialized(sce: ServletContextEvent): Unit = { - SshServer.start(sce.getServletContext) + val settings = loadSystemSettings() + if(settings.ssh){ + SshServer.start(sce.getServletContext, settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort)) + } } override def contextDestroyed(sce: ServletContextEvent): Unit = { - SshServer.stop() + if(loadSystemSettings().ssh){ + SshServer.stop() + } } } diff --git a/src/main/twirl/admin/system.scala.html b/src/main/twirl/admin/system.scala.html index 6594e29..fbc405d 100644 --- a/src/main/twirl/admin/system.scala.html +++ b/src/main/twirl/admin/system.scala.html @@ -56,6 +56,26 @@ + + +
+ +
+ +
+
+
+ +
+ + +
+
+
+
@@ -206,6 +226,10 @@ }