diff --git a/src/main/java/JettyLauncher.java b/src/main/java/JettyLauncher.java index 630c04b..1c2b6ca 100644 --- a/src/main/java/JettyLauncher.java +++ b/src/main/java/JettyLauncher.java @@ -41,12 +41,6 @@ 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; diff --git a/src/main/scala/gitbucket/core/controller/FileUploadController.scala b/src/main/scala/gitbucket/core/controller/FileUploadController.scala index 3d7a834..61516bb 100644 --- a/src/main/scala/gitbucket/core/controller/FileUploadController.scala +++ b/src/main/scala/gitbucket/core/controller/FileUploadController.scala @@ -17,6 +17,7 @@ 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 @@ 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 @@ } post("/tmp") { + setMultipartConfig() execute( { (file, fileId) => FileUtils @@ -55,6 +57,7 @@ } post("/file/:owner/:repository") { + setMultipartConfig() execute( { (file, fileId) => FileUtils.writeByteArrayToFile( @@ -70,6 +73,7 @@ } 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 @@ } post("/release/:owner/:repository/:tag") { + setMultipartConfigForLargeFile() session .get(Keys.Session.LoginAccount) .collect { @@ -150,6 +155,7 @@ post("/import") { import JDBCUtil._ + setMultipartConfig() session.get(Keys.Session.LoginAccount).collect { case loginAccount: Account if loginAccount.isAdmin => execute({ (file, fileId) => @@ -159,6 +165,18 @@ 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 { diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index d2cf204..ebb06dc 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -94,7 +94,13 @@ "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) { diff --git a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala index 5d02559..2f7dbc2 100644 --- a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala +++ b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala @@ -72,6 +72,10 @@ 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 @@ }, 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 @@ oidc: Option[OIDC], skinName: String, showMailAddress: Boolean, - webHook: WebHook + webHook: WebHook, + upload: Upload ) { def baseUrl(request: HttpServletRequest): String = @@ -258,6 +269,8 @@ 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 @@ 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 { diff --git a/src/main/scala/gitbucket/core/util/FileUtil.scala b/src/main/scala/gitbucket/core/util/FileUtil.scala index 1fc336a..1a30ace 100644 --- a/src/main/scala/gitbucket/core/util/FileUtil.scala +++ b/src/main/scala/gitbucket/core/util/FileUtil.scala @@ -92,12 +92,4 @@ 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) - } - } diff --git a/src/main/twirl/gitbucket/core/admin/settings.scala.html b/src/main/twirl/gitbucket/core/admin/settings.scala.html index 346b4652..22d945a 100644 --- a/src/main/twirl/gitbucket/core/admin/settings.scala.html +++ b/src/main/twirl/gitbucket/core/admin/settings.scala.html @@ -7,12 +7,16 @@
@settings_system(info)
+
+ @settings_integrations(info) +
@settings_authentication(info)
@@ -30,6 +34,9 @@ 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'); diff --git a/src/main/twirl/gitbucket/core/admin/settings_integrations.scala.html b/src/main/twirl/gitbucket/core/admin/settings_integrations.scala.html new file mode 100644 index 0000000..ea3412d --- /dev/null +++ b/src/main/twirl/gitbucket/core/admin/settings_integrations.scala.html @@ -0,0 +1,196 @@ +@(info: Option[Any])(implicit context: gitbucket.core.controller.Context) +@import gitbucket.core.util.DatabaseConfig + + + + +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ + + +
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ Send test mail to: + + +
+
+ + + +
+ +
+ +
+ + + +
+ +
+ +
+
+ +
+ +
+
+ diff --git a/src/main/twirl/gitbucket/core/admin/settings_system.scala.html b/src/main/twirl/gitbucket/core/admin/settings_system.scala.html index 6ed7748..1c98de0 100644 --- a/src/main/twirl/gitbucket/core/admin/settings_system.scala.html +++ b/src/main/twirl/gitbucket/core/admin/settings_system.scala.html @@ -151,6 +151,41 @@ + + +
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
@@ -164,142 +199,6 @@
- - - -
- -
- -
- - - -
- -
- -
-
-
- -
- - -
-
-
- -
- - -
-
-
- - - -
- -
- -
-
-
- -
- - -
-
-
- -
- - -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- Send test mail to: - - -
-
- - - -
- -
- -
- - - -
- -
- -
-
- -
- -
-
diff --git a/src/main/twirl/gitbucket/core/helper/attached.scala.html b/src/main/twirl/gitbucket/core/helper/attached.scala.html index 15a822a..8988445 100644 --- a/src/main/twirl/gitbucket/core/helper/attached.scala.html +++ b/src/main/twirl/gitbucket/core/helper/attached.scala.html @@ -65,9 +65,8 @@ } @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: "
\n
Uploading your files...
\n
\n
", success: function(file, id) { diff --git a/src/main/twirl/gitbucket/core/releases/form.scala.html b/src/main/twirl/gitbucket/core/releases/form.scala.html index ba15b2b..e69e509 100644 --- a/src/main/twirl/gitbucket/core/releases/form.scala.html +++ b/src/main/twirl/gitbucket/core/releases/form.scala.html @@ -71,10 +71,9 @@ }); $("#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: "
\n
Uploading your files...
\n
\n
", success: function(file, id) { var attach = diff --git a/src/main/twirl/gitbucket/core/repo/upload.scala.html b/src/main/twirl/gitbucket/core/repo/upload.scala.html index 6ddeb45..6aa19b1 100644 --- a/src/main/twirl/gitbucket/core/repo/upload.scala.html +++ b/src/main/twirl/gitbucket/core/repo/upload.scala.html @@ -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: "
\n
Uploading your files...
\n
\n
", success: function(file, id) { diff --git a/src/main/twirl/gitbucket/core/wiki/edit.scala.html b/src/main/twirl/gitbucket/core/wiki/edit.scala.html index 602a5f7..375233c 100644 --- a/src/main/twirl/gitbucket/core/wiki/edit.scala.html +++ b/src/main/twirl/gitbucket/core/wiki/edit.scala.html @@ -48,7 +48,8 @@ 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: "
\n
Uploading your files...
\n
\n
", success: function(file, id) { @@ -59,7 +60,8 @@ }); $('.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: "
\n
Uploading your files...
\n
\n
", success: function(file, id) { var attachFile = (file.type.match(/image\/.*/) ? '\n![' + file.name.split('.')[0] : '\n[' + file.name) + '](' + file.name + ')'; diff --git a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala index 1311d1a..ee38dc8 100644 --- a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala +++ b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala @@ -55,6 +55,12 @@ webHook = SystemSettingsService.WebHook( blockPrivateAddress = false, whitelist = Nil + ), + upload = SystemSettingsService.Upload( + maxFileSize = 3 * 1024 * 1024, + timeout = 30 * 10000, + largeMaxFileSize = 3 * 1024 * 1024, + largeTimeout = 30 * 10000 ) ) diff --git a/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala b/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala index 9cc1dfe..307c0a2 100644 --- a/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala +++ b/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala @@ -7,7 +7,7 @@ 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 @@ webHook = WebHook( blockPrivateAddress = false, whitelist = Nil + ), + upload = Upload( + maxFileSize = 3 * 1024 * 1024, + timeout = 30 * 10000, + largeMaxFileSize = 3 * 1024 * 1024, + largeTimeout = 30 * 10000 ) )