mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-07 22:15:51 +01:00
(refs #115)Start and stop sshd at the system settings
This commit is contained in:
@@ -4,6 +4,7 @@ import service.{AccountService, SystemSettingsService}
|
|||||||
import SystemSettingsService._
|
import SystemSettingsService._
|
||||||
import util.AdminAuthenticator
|
import util.AdminAuthenticator
|
||||||
import jp.sf.amateras.scalatra.forms._
|
import jp.sf.amateras.scalatra.forms._
|
||||||
|
import ssh.SshServer
|
||||||
|
|
||||||
class SystemSettingsController extends SystemSettingsControllerBase
|
class SystemSettingsController extends SystemSettingsControllerBase
|
||||||
with SystemSettingsService with AccountService with AdminAuthenticator
|
with SystemSettingsService with AccountService with AdminAuthenticator
|
||||||
@@ -16,6 +17,8 @@ trait SystemSettingsControllerBase extends ControllerBase {
|
|||||||
"allowAccountRegistration" -> trim(label("Account registration", boolean())),
|
"allowAccountRegistration" -> trim(label("Account registration", boolean())),
|
||||||
"gravatar" -> trim(label("Gravatar", boolean())),
|
"gravatar" -> trim(label("Gravatar", boolean())),
|
||||||
"notification" -> trim(label("Notification", boolean())),
|
"notification" -> trim(label("Notification", boolean())),
|
||||||
|
"ssh" -> trim(label("SSH access", boolean())),
|
||||||
|
"sshPort" -> trim(label("SSH port", optional(number()))),
|
||||||
"smtp" -> optionalIfNotChecked("notification", mapping(
|
"smtp" -> optionalIfNotChecked("notification", mapping(
|
||||||
"host" -> trim(label("SMTP Host", text(required))),
|
"host" -> trim(label("SMTP Host", text(required))),
|
||||||
"port" -> trim(label("SMTP Port", optional(number()))),
|
"port" -> trim(label("SMTP Port", optional(number()))),
|
||||||
@@ -47,6 +50,13 @@ trait SystemSettingsControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
post("/admin/system", form)(adminOnly { form =>
|
post("/admin/system", form)(adminOnly { form =>
|
||||||
saveSystemSettings(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."
|
flash += "info" -> "System settings has been updated."
|
||||||
redirect("/admin/system")
|
redirect("/admin/system")
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ trait SystemSettingsService {
|
|||||||
props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString)
|
props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString)
|
||||||
props.setProperty(Gravatar, settings.gravatar.toString)
|
props.setProperty(Gravatar, settings.gravatar.toString)
|
||||||
props.setProperty(Notification, settings.notification.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) {
|
if(settings.notification) {
|
||||||
settings.smtp.foreach { smtp =>
|
settings.smtp.foreach { smtp =>
|
||||||
props.setProperty(SmtpHost, smtp.host)
|
props.setProperty(SmtpHost, smtp.host)
|
||||||
@@ -60,6 +62,8 @@ trait SystemSettingsService {
|
|||||||
getValue(props, AllowAccountRegistration, false),
|
getValue(props, AllowAccountRegistration, false),
|
||||||
getValue(props, Gravatar, true),
|
getValue(props, Gravatar, true),
|
||||||
getValue(props, Notification, false),
|
getValue(props, Notification, false),
|
||||||
|
getValue(props, Ssh, false),
|
||||||
|
getOptionValue(props, SshPort, Some(DefaultSshPort)),
|
||||||
if(getValue(props, Notification, false)){
|
if(getValue(props, Notification, false)){
|
||||||
Some(Smtp(
|
Some(Smtp(
|
||||||
getValue(props, SmtpHost, ""),
|
getValue(props, SmtpHost, ""),
|
||||||
@@ -102,6 +106,8 @@ object SystemSettingsService {
|
|||||||
allowAccountRegistration: Boolean,
|
allowAccountRegistration: Boolean,
|
||||||
gravatar: Boolean,
|
gravatar: Boolean,
|
||||||
notification: Boolean,
|
notification: Boolean,
|
||||||
|
ssh: Boolean,
|
||||||
|
sshPort: Option[Int],
|
||||||
smtp: Option[Smtp],
|
smtp: Option[Smtp],
|
||||||
ldapAuthentication: Boolean,
|
ldapAuthentication: Boolean,
|
||||||
ldap: Option[Ldap])
|
ldap: Option[Ldap])
|
||||||
@@ -127,6 +133,7 @@ object SystemSettingsService {
|
|||||||
fromAddress: Option[String],
|
fromAddress: Option[String],
|
||||||
fromName: Option[String])
|
fromName: Option[String])
|
||||||
|
|
||||||
|
val DefaultSshPort = 29418
|
||||||
val DefaultSmtpPort = 25
|
val DefaultSmtpPort = 25
|
||||||
val DefaultLdapPort = 389
|
val DefaultLdapPort = 389
|
||||||
|
|
||||||
@@ -134,6 +141,8 @@ object SystemSettingsService {
|
|||||||
private val AllowAccountRegistration = "allow_account_registration"
|
private val AllowAccountRegistration = "allow_account_registration"
|
||||||
private val Gravatar = "gravatar"
|
private val Gravatar = "gravatar"
|
||||||
private val Notification = "notification"
|
private val Notification = "notification"
|
||||||
|
private val Ssh = "ssh"
|
||||||
|
private val SshPort = "ssh.port"
|
||||||
private val SmtpHost = "smtp.host"
|
private val SmtpHost = "smtp.host"
|
||||||
private val SmtpPort = "smtp.port"
|
private val SmtpPort = "smtp.port"
|
||||||
private val SmtpUser = "smtp.user"
|
private val SmtpUser = "smtp.user"
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ abstract class GitCommand(val command: String) extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = {
|
override protected def runTask(user: String): Unit = {
|
||||||
using(Git.open(getRepositoryDir(owner, repositoryName))) {
|
using(Git.open(getRepositoryDir(owner, repositoryName))) {
|
||||||
@@ -119,7 +119,7 @@ class GitCommandFactory(context: ServletContext) extends CommandFactory {
|
|||||||
override def createCommand(command: String): Command = {
|
override def createCommand(command: String): Command = {
|
||||||
logger.debug(s"command: $command")
|
logger.debug(s"command: $command")
|
||||||
command match {
|
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 GitCommand.CommandRegex("receive", owner, repoName) => new GitReceivePack(context, command)
|
||||||
case _ => new UnknownCommand(command)
|
case _ => new UnknownCommand(command)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,36 +4,36 @@ import javax.servlet.{ServletContext, ServletContextEvent, ServletContextListene
|
|||||||
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
|
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import util.Directory
|
import util.Directory
|
||||||
|
import service.SystemSettingsService
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
object SshServer {
|
object SshServer {
|
||||||
private val logger = LoggerFactory.getLogger(SshServer.getClass)
|
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 server = org.apache.sshd.SshServer.setUpDefaultServer()
|
||||||
|
private val active = new AtomicBoolean(false);
|
||||||
|
|
||||||
private def configure(context: ServletContext) = {
|
private def configure(context: ServletContext, port: Int) = {
|
||||||
server.setPort(DEFAULT_PORT) // TODO read from config
|
server.setPort(port)
|
||||||
server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(s"${Directory.GitBucketHome}/gitbucket.ser"))
|
server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(s"${Directory.GitBucketHome}/gitbucket.ser"))
|
||||||
server.setPublickeyAuthenticator(new PublicKeyAuthenticator(context))
|
server.setPublickeyAuthenticator(new PublicKeyAuthenticator(context))
|
||||||
server.setCommandFactory(new GitCommandFactory(context))
|
server.setCommandFactory(new GitCommandFactory(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
def start(context: ServletContext) = this.synchronized {
|
def start(context: ServletContext, port: Int) = {
|
||||||
if (SSH_SERVICE_ENABLE) {
|
if(active.compareAndSet(false, true)){
|
||||||
|
configure(context, port)
|
||||||
configure(context)
|
|
||||||
server.start()
|
server.start()
|
||||||
logger.info(s"Start SSH Server Listen on ${server.getPort}")
|
logger.info(s"Start SSH Server Listen on ${server.getPort}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def stop() = {
|
def stop() = {
|
||||||
server.stop(true)
|
if(active.compareAndSet(true, false)){
|
||||||
|
server.stop(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def isActive = active.get
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -41,16 +41,20 @@ object SshServer {
|
|||||||
*
|
*
|
||||||
* How to use:
|
* How to use:
|
||||||
* git clone ssh://username@host_or_ip:29418/owner/repository_name.git
|
* 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 = {
|
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 = {
|
override def contextDestroyed(sce: ServletContextEvent): Unit = {
|
||||||
SshServer.stop()
|
if(loadSystemSettings().ssh){
|
||||||
|
SshServer.stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,26 @@
|
|||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<!--====================================================================-->
|
<!--====================================================================-->
|
||||||
|
<!-- SSH access -->
|
||||||
|
<!--====================================================================-->
|
||||||
|
<hr>
|
||||||
|
<label class="strong">SSH access</label>
|
||||||
|
<fieldset>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" id="ssh" name="ssh"@if(settings.ssh){ checked}/>
|
||||||
|
Enable SSH access to git repository
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<div class="form-horizontal ssh">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="sshPort">SSH Port</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="sshPort" name="sshPort" value="@settings.sshPort"/>
|
||||||
|
<span id="error-sshPort" class="error"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--====================================================================-->
|
||||||
<!-- Authentication -->
|
<!-- Authentication -->
|
||||||
<!--====================================================================-->
|
<!--====================================================================-->
|
||||||
<hr>
|
<hr>
|
||||||
@@ -206,6 +226,10 @@
|
|||||||
}
|
}
|
||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
|
$('#ssh').change(function(){
|
||||||
|
$('.ssh input').prop('disabled', !$(this).prop('checked'));
|
||||||
|
}).change();
|
||||||
|
|
||||||
$('#notification').change(function(){
|
$('#notification').change(function(){
|
||||||
$('.notification input').prop('disabled', !$(this).prop('checked'));
|
$('.notification input').prop('disabled', !$(this).prop('checked'));
|
||||||
}).change();
|
}).change();
|
||||||
|
|||||||
Reference in New Issue
Block a user