mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-12 08:25:50 +01:00
Restructure settings UI (#2413)
This commit is contained in:
@@ -41,12 +41,6 @@ public class JettyLauncher {
|
||||
case "--prefix":
|
||||
contextPath = dim[1];
|
||||
break;
|
||||
case "--max_file_size":
|
||||
System.setProperty("gitbucket.maxFileSize", dim[1]);
|
||||
break;
|
||||
case "--upload_timeout":
|
||||
System.setProperty("gitbucket.UploadTimeout", dim[1]);
|
||||
break;
|
||||
case "--gitbucket.home":
|
||||
System.setProperty("gitbucket.home", dim[1]);
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.scalatra.servlet.{FileItem, FileUploadSupport, MultipartConfig}
|
||||
import org.apache.commons.io.{FileUtils, IOUtils}
|
||||
|
||||
import scala.util.Using
|
||||
import gitbucket.core.service.SystemSettingsService
|
||||
|
||||
/**
|
||||
* Provides Ajax based file upload functionality.
|
||||
@@ -28,11 +29,11 @@ class FileUploadController
|
||||
with FileUploadSupport
|
||||
with RepositoryService
|
||||
with AccountService
|
||||
with ReleaseService {
|
||||
|
||||
configureMultipartHandling(MultipartConfig(maxFileSize = Some(FileUtil.MaxFileSize)))
|
||||
with ReleaseService
|
||||
with SystemSettingsService {
|
||||
|
||||
post("/image") {
|
||||
setMultipartConfig()
|
||||
execute(
|
||||
{ (file, fileId) =>
|
||||
FileUtils
|
||||
@@ -44,6 +45,7 @@ class FileUploadController
|
||||
}
|
||||
|
||||
post("/tmp") {
|
||||
setMultipartConfig()
|
||||
execute(
|
||||
{ (file, fileId) =>
|
||||
FileUtils
|
||||
@@ -55,6 +57,7 @@ class FileUploadController
|
||||
}
|
||||
|
||||
post("/file/:owner/:repository") {
|
||||
setMultipartConfig()
|
||||
execute(
|
||||
{ (file, fileId) =>
|
||||
FileUtils.writeByteArrayToFile(
|
||||
@@ -70,6 +73,7 @@ class FileUploadController
|
||||
}
|
||||
|
||||
post("/wiki/:owner/:repository") {
|
||||
setMultipartConfig()
|
||||
// Don't accept not logged-in users
|
||||
session.get(Keys.Session.LoginAccount).collect {
|
||||
case loginAccount: Account =>
|
||||
@@ -128,6 +132,7 @@ class FileUploadController
|
||||
}
|
||||
|
||||
post("/release/:owner/:repository/:tag") {
|
||||
setMultipartConfigForLargeFile()
|
||||
session
|
||||
.get(Keys.Session.LoginAccount)
|
||||
.collect {
|
||||
@@ -150,6 +155,7 @@ class FileUploadController
|
||||
|
||||
post("/import") {
|
||||
import JDBCUtil._
|
||||
setMultipartConfig()
|
||||
session.get(Keys.Session.LoginAccount).collect {
|
||||
case loginAccount: Account if loginAccount.isAdmin =>
|
||||
execute({ (file, fileId) =>
|
||||
@@ -159,6 +165,18 @@ class FileUploadController
|
||||
redirect("/admin/data")
|
||||
}
|
||||
|
||||
private def setMultipartConfig(): Unit = {
|
||||
val settings = loadSystemSettings()
|
||||
val config = MultipartConfig(maxFileSize = Some(settings.upload.maxFileSize))
|
||||
config.apply(request.getServletContext())
|
||||
}
|
||||
|
||||
private def setMultipartConfigForLargeFile(): Unit = {
|
||||
val settings = loadSystemSettings()
|
||||
val config = MultipartConfig(maxFileSize = Some(settings.upload.largeMaxFileSize))
|
||||
config.apply(request.getServletContext())
|
||||
}
|
||||
|
||||
private def onlyWikiEditable(owner: String, repository: String, loginAccount: Account)(action: => Any): Any = {
|
||||
implicit val session = Database.getSession(request)
|
||||
getRepository(owner, repository) match {
|
||||
|
||||
@@ -94,7 +94,13 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
||||
"webhook" -> mapping(
|
||||
"blockPrivateAddress" -> trim(label("Block private address", boolean())),
|
||||
"whitelist" -> trim(label("Whitelist", multiLineText()))
|
||||
)(WebHook.apply)
|
||||
)(WebHook.apply),
|
||||
"upload" -> mapping(
|
||||
"maxFileSize" -> trim(label("Max file size", long(required))),
|
||||
"timeout" -> trim(label("Timeout", long(required))),
|
||||
"largeMaxFileSize" -> trim(label("Max file size for large file", long(required))),
|
||||
"largeTimeout" -> trim(label("Timeout for large file", long(required)))
|
||||
)(Upload.apply)
|
||||
)(SystemSettings.apply).verifying { settings =>
|
||||
Vector(
|
||||
if (settings.ssh.enabled && settings.baseUrl.isEmpty) {
|
||||
|
||||
@@ -72,6 +72,10 @@ trait SystemSettingsService {
|
||||
props.setProperty(ShowMailAddress, settings.showMailAddress.toString)
|
||||
props.setProperty(WebHookBlockPrivateAddress, settings.webHook.blockPrivateAddress.toString)
|
||||
props.setProperty(WebHookWhitelist, settings.webHook.whitelist.mkString("\n"))
|
||||
props.setProperty(UploadMaxFileSize, settings.upload.maxFileSize.toString)
|
||||
props.setProperty(UploadTimeout, settings.upload.timeout.toString)
|
||||
props.setProperty(UploadLargeMaxFileSize, settings.upload.largeMaxFileSize.toString)
|
||||
props.setProperty(UploadLargeTimeout, settings.upload.largeTimeout.toString)
|
||||
|
||||
Using.resource(new java.io.FileOutputStream(GitBucketConf)) { out =>
|
||||
props.store(out, null)
|
||||
@@ -149,7 +153,13 @@ trait SystemSettingsService {
|
||||
},
|
||||
getValue(props, SkinName, "skin-blue"),
|
||||
getValue(props, ShowMailAddress, false),
|
||||
WebHook(getValue(props, WebHookBlockPrivateAddress, false), getSeqValue(props, WebHookWhitelist, ""))
|
||||
WebHook(getValue(props, WebHookBlockPrivateAddress, false), getSeqValue(props, WebHookWhitelist, "")),
|
||||
Upload(
|
||||
getValue(props, UploadMaxFileSize, 3 * 1024 * 1024),
|
||||
getValue(props, UploadTimeout, 3 * 10000),
|
||||
getValue(props, UploadLargeMaxFileSize, 3 * 1024 * 1024),
|
||||
getValue(props, UploadLargeTimeout, 3 * 10000)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -179,7 +189,8 @@ object SystemSettingsService {
|
||||
oidc: Option[OIDC],
|
||||
skinName: String,
|
||||
showMailAddress: Boolean,
|
||||
webHook: WebHook
|
||||
webHook: WebHook,
|
||||
upload: Upload
|
||||
) {
|
||||
|
||||
def baseUrl(request: HttpServletRequest): String =
|
||||
@@ -258,6 +269,8 @@ object SystemSettingsService {
|
||||
|
||||
case class WebHook(blockPrivateAddress: Boolean, whitelist: Seq[String])
|
||||
|
||||
case class Upload(maxFileSize: Long, timeout: Long, largeMaxFileSize: Long, largeTimeout: Long)
|
||||
|
||||
val DefaultSshPort = 29418
|
||||
val DefaultSmtpPort = 25
|
||||
val DefaultLdapPort = 389
|
||||
@@ -302,13 +315,12 @@ object SystemSettingsService {
|
||||
private val OidcJwsAlgorithm = "oidc.jws_algorithm"
|
||||
private val SkinName = "skinName"
|
||||
private val ShowMailAddress = "showMailAddress"
|
||||
private val PluginNetworkInstall = "plugin.networkInstall"
|
||||
private val PluginProxyHost = "plugin.proxy.host"
|
||||
private val PluginProxyPort = "plugin.proxy.port"
|
||||
private val PluginProxyUser = "plugin.proxy.user"
|
||||
private val PluginProxyPassword = "plugin.proxy.password"
|
||||
private val WebHookBlockPrivateAddress = "webhook.block_private_address"
|
||||
private val WebHookWhitelist = "webhook.whitelist"
|
||||
private val UploadMaxFileSize = "upload.maxFileSize"
|
||||
private val UploadTimeout = "upload.timeout"
|
||||
private val UploadLargeMaxFileSize = "upload.largeMaxFileSize"
|
||||
private val UploadLargeTimeout = "upload.largeTimeout"
|
||||
|
||||
private def getValue[A: ClassTag](props: java.util.Properties, key: String, default: A): A = {
|
||||
getConfigValue(key).getOrElse {
|
||||
|
||||
@@ -92,12 +92,4 @@ object FileUtil {
|
||||
name
|
||||
}
|
||||
|
||||
lazy val MaxFileSize: Long = {
|
||||
ConfigUtil.getConfigValue[Long]("gitbucket.maxFileSize").getOrElse(3 * 1024 * 1024)
|
||||
}
|
||||
|
||||
lazy val UploadTimeout: Long = {
|
||||
ConfigUtil.getConfigValue[Long]("gitbucket.UploadTimeout").getOrElse(3 * 10000)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,12 +7,16 @@
|
||||
<form action="@context.path/admin/system" method="POST" validate="true" class="form-horizontal" autocomplete="off">
|
||||
<ul class="nav nav-tabs fill-width" id="pullreq-tab">
|
||||
<li><a href="#system">System settings</a></li>
|
||||
<li><a href="#integrations">Integrations</a></li>
|
||||
<li><a href="#authentication">Authentication</a></li>
|
||||
</ul>
|
||||
<div class="tab-content fill-width" style="padding-top: 20px;">
|
||||
<div class="tab-pane" id="system">
|
||||
@settings_system(info)
|
||||
</div>
|
||||
<div class="tab-pane" id="integrations">
|
||||
@settings_integrations(info)
|
||||
</div>
|
||||
<div class="tab-pane" id="authentication">
|
||||
@settings_authentication(info)
|
||||
</div>
|
||||
@@ -30,6 +34,9 @@ $(function(){
|
||||
if(location.hash == '#authentication'){
|
||||
$('li:has(a[href="#authentication"])').addClass('active');
|
||||
$('div#authentication').addClass('active');
|
||||
} else if(location.hash == '#integrations'){
|
||||
$('li:has(a[href="#integrations"])').addClass('active');
|
||||
$('div#integrations').addClass('active');
|
||||
} else {
|
||||
$('li:has(a[href="#system"])').addClass('active');
|
||||
$('div#system').addClass('active');
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
@(info: Option[Any])(implicit context: gitbucket.core.controller.Context)
|
||||
@import gitbucket.core.util.DatabaseConfig
|
||||
<!--====================================================================-->
|
||||
<!-- Services -->
|
||||
<!--====================================================================-->
|
||||
<label class="strong">Services</label>
|
||||
<fieldset>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="gravatar"@if(context.settings.gravatar){ checked}/>
|
||||
Use Gravatar for profile images
|
||||
</label>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- SSH access -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">SSH access</label>
|
||||
<fieldset>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="sshEnabled" name="ssh.enabled"@if(context.settings.ssh.enabled){ checked}/>
|
||||
Enable SSH access to git repository
|
||||
<span class="muted normal">(Both SSH host and Base URL are required if SSH access is enabled)</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<div class="ssh">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="sshHost">SSH host</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="sshHost" name="ssh.host" class="form-control" value="@context.settings.ssh.sshHost"/>
|
||||
<span id="error-ssh_host" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="sshPort">SSH port</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="sshPort" name="ssh.port" class="form-control" value="@context.settings.ssh.sshPort"/>
|
||||
<span id="error-ssh_port" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--====================================================================-->
|
||||
<!-- Communication email -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Communication</label>
|
||||
<fieldset>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="useSMTP" name="useSMTP" @if(context.settings.useSMTP){ checked}/>
|
||||
SMTP
|
||||
<span class="muted normal">(Enable notification as well as SMTP configuration if you want to send notification email too)</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<div class="useSMTP">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpHost">SMTP host</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="smtpHost" name="smtp.host" class="form-control" value="@context.settings.smtp.map(_.host)"/>
|
||||
<span id="error-smtp_host" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpPort">SMTP port</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="smtpPort" name="smtp.port" class="form-control input-mini" value="@context.settings.smtp.map(_.port)"/>
|
||||
<span id="error-smtp_port" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpUser">SMTP user</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="smtpUser" name="smtp.user" class="form-control" value="@context.settings.smtp.map(_.user)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpPassword">SMTP password</label>
|
||||
<div class="col-md-10">
|
||||
<input type="password" id="smtpPassword" name="smtp.password" class="form-control" value="@context.settings.smtp.map(_.password)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpSsl">Enable SSL</label>
|
||||
<div class="col-md-10">
|
||||
<input type="checkbox" id="smtpSsl" name="smtp.ssl"@if(context.settings.smtp.flatMap(_.ssl).getOrElse(false)){ checked}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpStarttls">Enable STARTTLS</label>
|
||||
<div class="col-md-10">
|
||||
<input type="checkbox" id="smtpStarttls" name="smtp.starttls"@if(context.settings.smtp.flatMap(_.starttls).getOrElse(false)){ checked}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="fromAddress">FROM address</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="fromAddress" name="smtp.fromAddress" class="form-control" value="@context.settings.smtp.map(_.fromAddress)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="fromName">FROM name</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="fromName" name="smtp.fromName" class="form-control" value="@context.settings.smtp.map(_.fromName)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
Send test mail to:
|
||||
<input type="text" id="testAddress" size="30"/>
|
||||
<input type="button" id="sendTestMail" value="Send"/>
|
||||
</div>
|
||||
</div>
|
||||
<!--====================================================================-->
|
||||
<!-- Notification email -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Notifications</label>
|
||||
<fieldset>
|
||||
<label class="checkbox" for="notification">
|
||||
<input type="checkbox" id="notification" name="notification"@if(context.settings.notification){ checked}/>
|
||||
Send notifications
|
||||
</label>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- Web hook -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Web hook</label>
|
||||
<fieldset>
|
||||
<label class="checkbox" for="blockPrivateAddress">
|
||||
<input type="checkbox" id="blockPrivateAddress" name="webhook.blockPrivateAddress"@if(context.settings.webHook.blockPrivateAddress){ checked}/>
|
||||
Block sending to private addresses
|
||||
</label>
|
||||
</fieldset>
|
||||
<div class="webhook">
|
||||
<label><span class="strong">IP whitelist</span></label>
|
||||
<fieldset>
|
||||
<textarea name="webhook.whitelist" class="form-control" style="height: 100px;">@context.settings.webHook.whitelist.mkString("\n")</textarea>
|
||||
</fieldset>
|
||||
</div>
|
||||
<script>
|
||||
$(function(){
|
||||
$('#sendTestMail').click(function(){
|
||||
var host = $('#smtpHost' ).val();
|
||||
var port = $('#smtpPort' ).val();
|
||||
var user = $('#smtpUser' ).val();
|
||||
var password = $('#smtpPassword').val();
|
||||
var ssl = $('#smtpSsl' ).prop('checked');
|
||||
var starttls = $('#smtpStarttls').prop('checked');
|
||||
var fromAddress = $('#fromAddress' ).val();
|
||||
var fromName = $('#fromName' ).val();
|
||||
var testAddress = $('#testAddress' ).val();
|
||||
|
||||
if(host == ''){
|
||||
alert('SMTP Host is required.');
|
||||
$('#smtpHost').focus();
|
||||
} else if(testAddress == ''){
|
||||
alert('Destination is required.');
|
||||
$('#testAddress').focus();
|
||||
} else {
|
||||
$.post('@context.path/admin/system/sendmail', {
|
||||
'smtp.host': host,
|
||||
'smtp.port': port,
|
||||
'smtp.user': user,
|
||||
'smtp.password': password,
|
||||
'smtp.ssl': ssl,
|
||||
'smtp.starttls': starttls,
|
||||
'smtp.fromAddress': fromAddress,
|
||||
'smtp.fromName': fromName,
|
||||
'testAddress': testAddress
|
||||
}, function(data, status){
|
||||
if(data != ''){
|
||||
alert(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#sshEnabled').change(function(){
|
||||
$('.ssh input').prop('disabled', !$(this).prop('checked'));
|
||||
}).change();
|
||||
|
||||
$('#useSMTP').change(function(){
|
||||
$('.useSMTP input').prop('disabled', !$(this).prop('checked'));
|
||||
|
||||
// With only SMTP in current version, notification cannot be enabled if no communication channel exists
|
||||
$('#notification').prop('disabled', !$(this).prop('checked'));
|
||||
|
||||
if (!$(this).prop('checked')) {
|
||||
// With only SMTP in current version, if SMTP is unchecked then we disable notification
|
||||
$('#notification').prop('checked', false);
|
||||
}
|
||||
}).change();
|
||||
|
||||
$('#blockPrivateAddress').change(function(){
|
||||
$('.webhook textarea').prop('disabled', !$(this).prop('checked'));
|
||||
}).change();
|
||||
});
|
||||
</script>
|
||||
@@ -151,6 +151,41 @@
|
||||
</label>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- File upload -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">File upload</label>
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="uploadMaxFileSize">Max size</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="uploadMaxFileSize" name="upload.maxFileSize" class="form-control input-mini" value="@context.settings.upload.maxFileSize"/>
|
||||
<span id="error-upload_maxFileSize" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="uploadTimeout">Timeout</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="uploadTimeout" name="upload.timeout" class="form-control input-mini" value="@context.settings.upload.timeout"/>
|
||||
<span id="error-upload_timeout" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="uploadLargeMaxFileSize">Max size for large files</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="uploadLargeMaxFileSize" name="upload.largeMaxFileSize" class="form-control input-mini" value="@context.settings.upload.largeMaxFileSize"/>
|
||||
<span id="error-upload_largeMaxFileSize" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="uploadLargeTimeout">Timeout for large files</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="uploadLargeTimeout" name="upload.largeTimeout" class="form-control input-mini" value="@context.settings.upload.largeTimeout"/>
|
||||
<span id="error-upload_largeTimeout" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- Activity -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
@@ -164,142 +199,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- Services -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Services</label>
|
||||
<fieldset>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="gravatar"@if(context.settings.gravatar){ checked}/>
|
||||
Use Gravatar for profile images
|
||||
</label>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- SSH access -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">SSH access</label>
|
||||
<fieldset>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="sshEnabled" name="ssh.enabled"@if(context.settings.ssh.enabled){ checked}/>
|
||||
Enable SSH access to git repository
|
||||
<span class="muted normal">(Both SSH host and Base URL are required if SSH access is enabled)</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<div class="ssh">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="sshHost">SSH host</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="sshHost" name="ssh.host" class="form-control" value="@context.settings.ssh.sshHost"/>
|
||||
<span id="error-ssh_host" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="sshPort">SSH port</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="sshPort" name="ssh.port" class="form-control" value="@context.settings.ssh.sshPort"/>
|
||||
<span id="error-ssh_port" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--====================================================================-->
|
||||
<!-- Communication email -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Communication</label>
|
||||
<fieldset>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="useSMTP" name="useSMTP" @if(context.settings.useSMTP){ checked}/>
|
||||
SMTP
|
||||
<span class="muted normal">(Enable notification as well as SMTP configuration if you want to send notification email too)</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
<div class="useSMTP">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpHost">SMTP host</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="smtpHost" name="smtp.host" class="form-control" value="@context.settings.smtp.map(_.host)"/>
|
||||
<span id="error-smtp_host" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpPort">SMTP port</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="smtpPort" name="smtp.port" class="form-control input-mini" value="@context.settings.smtp.map(_.port)"/>
|
||||
<span id="error-smtp_port" class="error"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpUser">SMTP user</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="smtpUser" name="smtp.user" class="form-control" value="@context.settings.smtp.map(_.user)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpPassword">SMTP password</label>
|
||||
<div class="col-md-10">
|
||||
<input type="password" id="smtpPassword" name="smtp.password" class="form-control" value="@context.settings.smtp.map(_.password)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpSsl">Enable SSL</label>
|
||||
<div class="col-md-10">
|
||||
<input type="checkbox" id="smtpSsl" name="smtp.ssl"@if(context.settings.smtp.flatMap(_.ssl).getOrElse(false)){ checked}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="smtpStarttls">Enable STARTTLS</label>
|
||||
<div class="col-md-10">
|
||||
<input type="checkbox" id="smtpStarttls" name="smtp.starttls"@if(context.settings.smtp.flatMap(_.starttls).getOrElse(false)){ checked}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="fromAddress">FROM address</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="fromAddress" name="smtp.fromAddress" class="form-control" value="@context.settings.smtp.map(_.fromAddress)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2" for="fromName">FROM name</label>
|
||||
<div class="col-md-10">
|
||||
<input type="text" id="fromName" name="smtp.fromName" class="form-control" value="@context.settings.smtp.map(_.fromName)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
Send test mail to:
|
||||
<input type="text" id="testAddress" size="30"/>
|
||||
<input type="button" id="sendTestMail" value="Send"/>
|
||||
</div>
|
||||
</div>
|
||||
<!--====================================================================-->
|
||||
<!-- Notification email -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Notifications</label>
|
||||
<fieldset>
|
||||
<label class="checkbox" for="notification">
|
||||
<input type="checkbox" id="notification" name="notification"@if(context.settings.notification){ checked}/>
|
||||
Send notifications
|
||||
</label>
|
||||
</fieldset>
|
||||
<!--====================================================================-->
|
||||
<!-- Web hook -->
|
||||
<!--====================================================================-->
|
||||
<hr>
|
||||
<label class="strong">Web hook</label>
|
||||
<fieldset>
|
||||
<label class="checkbox" for="blockPrivateAddress">
|
||||
<input type="checkbox" id="blockPrivateAddress" name="webhook.blockPrivateAddress"@if(context.settings.webHook.blockPrivateAddress){ checked}/>
|
||||
Block sending to private addresses
|
||||
</label>
|
||||
</fieldset>
|
||||
<div class="webhook">
|
||||
<label><span class="strong">IP whitelist</span></label>
|
||||
<fieldset>
|
||||
<textarea name="webhook.whitelist" class="form-control" style="height: 100px;">@context.settings.webHook.whitelist.mkString("\n")</textarea>
|
||||
</fieldset>
|
||||
</div>
|
||||
<script>
|
||||
$(function(){
|
||||
$('#skinName').change(function(evt) {
|
||||
@@ -309,61 +208,5 @@ $(function(){
|
||||
themeCss.attr('href', themeCss.attr('href').replace(oldVal, that.val()));
|
||||
$(document.body).removeClass(oldVal).addClass(that.val());
|
||||
});
|
||||
|
||||
$('#sendTestMail').click(function(){
|
||||
var host = $('#smtpHost' ).val();
|
||||
var port = $('#smtpPort' ).val();
|
||||
var user = $('#smtpUser' ).val();
|
||||
var password = $('#smtpPassword').val();
|
||||
var ssl = $('#smtpSsl' ).prop('checked');
|
||||
var starttls = $('#smtpStarttls').prop('checked');
|
||||
var fromAddress = $('#fromAddress' ).val();
|
||||
var fromName = $('#fromName' ).val();
|
||||
var testAddress = $('#testAddress' ).val();
|
||||
|
||||
if(host == ''){
|
||||
alert('SMTP Host is required.');
|
||||
$('#smtpHost').focus();
|
||||
} else if(testAddress == ''){
|
||||
alert('Destination is required.');
|
||||
$('#testAddress').focus();
|
||||
} else {
|
||||
$.post('@context.path/admin/system/sendmail', {
|
||||
'smtp.host': host,
|
||||
'smtp.port': port,
|
||||
'smtp.user': user,
|
||||
'smtp.password': password,
|
||||
'smtp.ssl': ssl,
|
||||
'smtp.starttls': starttls,
|
||||
'smtp.fromAddress': fromAddress,
|
||||
'smtp.fromName': fromName,
|
||||
'testAddress': testAddress
|
||||
}, function(data, status){
|
||||
if(data != ''){
|
||||
alert(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#sshEnabled').change(function(){
|
||||
$('.ssh input').prop('disabled', !$(this).prop('checked'));
|
||||
}).change();
|
||||
|
||||
$('#useSMTP').change(function(){
|
||||
$('.useSMTP input').prop('disabled', !$(this).prop('checked'));
|
||||
|
||||
// With only SMTP in current version, notification cannot be enabled if no communication channel exists
|
||||
$('#notification').prop('disabled', !$(this).prop('checked'));
|
||||
|
||||
if (!$(this).prop('checked')) {
|
||||
// With only SMTP in current version, if SMTP is unchecked then we disable notification
|
||||
$('#notification').prop('checked', false);
|
||||
}
|
||||
}).change();
|
||||
|
||||
$('#blockPrivateAddress').change(function(){
|
||||
$('.webhook textarea').prop('disabled', !$(this).prop('checked'));
|
||||
}).change();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -65,9 +65,8 @@ $(function(){
|
||||
}
|
||||
@dropzone(clickable: Boolean, textareaId: Option[String]) = {
|
||||
url: '@context.path/upload/file/@repository.owner/@repository.name',
|
||||
maxFilesize: @{FileUtil.MaxFileSize / 1024 / 1024},
|
||||
//timeout defaults to 30 secs
|
||||
timeout: @{FileUtil.UploadTimeout},
|
||||
maxFilesize: @{context.settings.upload.maxFileSize / 1024 / 1024},
|
||||
timeout: @{context.settings.upload.timeout},
|
||||
clickable: @clickable,
|
||||
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
|
||||
success: function(file, id) {
|
||||
|
||||
@@ -71,10 +71,9 @@ $(function(){
|
||||
});
|
||||
|
||||
$("#drop").dropzone({
|
||||
maxFilesize: @{gitbucket.core.util.FileUtil.MaxFileSize / 1024 / 1024},
|
||||
url: '@context.path/upload/release/@repository.owner/@repository.name/@helpers.encodeRefName(tag.name)',
|
||||
//timeout defaults to 30 secs
|
||||
timeout: @{gitbucket.core.util.FileUtil.UploadTimeout},
|
||||
maxFilesize: @{context.settings.upload.largeMaxFileSize / 1024 / 1024},
|
||||
timeout: @{context.settings.upload.largeTimeout},
|
||||
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
|
||||
success: function(file, id) {
|
||||
var attach =
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
$(function(){
|
||||
$('#upload-area').dropzone({
|
||||
url: '@context.path/upload/tmp',
|
||||
maxFilesize: @{FileUtil.MaxFileSize / 1024 / 1024},
|
||||
maxFilesize: @{context.settings.upload.maxFileSize / 1024 / 1024},
|
||||
timeout: @{context.settings.upload.timeout},
|
||||
clickable: true,
|
||||
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
|
||||
success: function(file, id) {
|
||||
|
||||
@@ -48,7 +48,8 @@ $(function(){
|
||||
try {
|
||||
$('#content1').dropzone({
|
||||
url: '@context.path/upload/wiki/@repository.owner/@repository.name',
|
||||
maxFilesize: @{FileUtil.MaxFileSize / 1024 / 1024},
|
||||
maxFilesize: @{context.settings.upload.maxFileSize / 1024 / 1024},
|
||||
timeout: @{context.settings.upload.timeout},
|
||||
clickable: false,
|
||||
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
|
||||
success: function(file, id) {
|
||||
@@ -59,7 +60,8 @@ $(function(){
|
||||
});
|
||||
$('.clickable').dropzone({
|
||||
url: '@context.path/upload/wiki/@repository.owner/@repository.name',
|
||||
maxFilesize: @{FileUtil.MaxFileSize / 1024 / 1024},
|
||||
maxFilesize: @{context.settings.upload.maxFileSize / 1024 / 1024},
|
||||
timeout: @{context.settings.upload.timeout},
|
||||
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
|
||||
success: function(file, id) {
|
||||
var attachFile = (file.type.match(/image\/.*/) ? '\n![' + file.name.split('.')[0] : '\n[' + file.name) + '](' + file.name + ')';
|
||||
|
||||
@@ -55,6 +55,12 @@ trait ServiceSpecBase extends MockitoSugar {
|
||||
webHook = SystemSettingsService.WebHook(
|
||||
blockPrivateAddress = false,
|
||||
whitelist = Nil
|
||||
),
|
||||
upload = SystemSettingsService.Upload(
|
||||
maxFileSize = 3 * 1024 * 1024,
|
||||
timeout = 30 * 10000,
|
||||
largeMaxFileSize = 3 * 1024 * 1024,
|
||||
largeTimeout = 30 * 10000
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import javax.servlet.http.{HttpServletRequest, HttpSession}
|
||||
import gitbucket.core.controller.Context
|
||||
import gitbucket.core.model.Account
|
||||
import gitbucket.core.service.RequestCache
|
||||
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings, WebHook}
|
||||
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings, WebHook, Upload}
|
||||
import org.mockito.Mockito._
|
||||
import org.scalatest.FunSpec
|
||||
import org.scalatestplus.mockito.MockitoSugar
|
||||
@@ -141,6 +141,12 @@ class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
||||
webHook = WebHook(
|
||||
blockPrivateAddress = false,
|
||||
whitelist = Nil
|
||||
),
|
||||
upload = Upload(
|
||||
maxFileSize = 3 * 1024 * 1024,
|
||||
timeout = 30 * 10000,
|
||||
largeMaxFileSize = 3 * 1024 * 1024,
|
||||
largeTimeout = 30 * 10000
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user