diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index b51b227..0039dc0 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -46,7 +46,7 @@ "ssh" -> mapping( "enabled" -> trim(label("SSH access", boolean())), "host" -> trim(label("SSH host", optional(text()))), - "port" -> trim(label("SSH port", optional(number()))), + "port" -> trim(label("SSH port", optional(number()))) )(Ssh.apply), "useSMTP" -> trim(label("SMTP", boolean())), "smtp" -> optionalIfNotChecked( @@ -91,6 +91,7 @@ )(OIDC.apply) ), "skinName" -> trim(label("AdminLTE skin name", text(required))), + "userDefinedCss" -> trim(label("User-defined CSS", optional(text()))), "showMailAddress" -> trim(label("Show mail address", boolean())), "webhook" -> mapping( "blockPrivateAddress" -> trim(label("Block private address", boolean())), @@ -536,24 +537,26 @@ } } - private def members: Constraint = new Constraint() { - override def validate(name: String, value: String, messages: Messages): Option[String] = { - if (value.split(",").exists { - _.split(":") match { case Array(userName, isManager) => isManager.toBoolean } - }) None - else Some("Must select one manager at least.") - } - } - - protected def disableByNotYourself(paramName: String): Constraint = new Constraint() { - override def validate(name: String, value: String, messages: Messages): Option[String] = { - params.get(paramName).flatMap { userName => - if (userName == context.loginAccount.get.userName && params.get("removed") == Some("true")) - Some("You can't disable your account yourself") - else - None + private def members: Constraint = + new Constraint() { + override def validate(name: String, value: String, messages: Messages): Option[String] = { + if (value.split(",").exists { + _.split(":") match { case Array(userName, isManager) => isManager.toBoolean } + }) None + else Some("Must select one manager at least.") } } - } + + protected def disableByNotYourself(paramName: String): Constraint = + new Constraint() { + override def validate(name: String, value: String, messages: Messages): Option[String] = { + params.get(paramName).flatMap { userName => + if (userName == context.loginAccount.get.userName && params.get("removed") == Some("true")) + Some("You can't disable your account yourself") + else + None + } + } + } } diff --git a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala index 0b40426..44bff3f 100644 --- a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala +++ b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala @@ -70,6 +70,7 @@ } } props.setProperty(SkinName, settings.skinName.toString) + settings.userDefinedCss.foreach(x => props.setProperty(UserDefinedCss, x)) props.setProperty(ShowMailAddress, settings.showMailAddress.toString) props.setProperty(WebHookBlockPrivateAddress, settings.webHook.blockPrivateAddress.toString) props.setProperty(WebHookWhitelist, settings.webHook.whitelist.mkString("\n")) @@ -106,7 +107,11 @@ getOptionValue[String](props, SshHost, None).map(_.trim), getOptionValue(props, SshPort, Some(DefaultSshPort)) ), - getValue(props, UseSMTP, getValue(props, Notification, false)), // handle migration scenario from only notification to useSMTP + getValue( + props, + UseSMTP, + getValue(props, Notification, false) + ), // handle migration scenario from only notification to useSMTP if (getValue(props, UseSMTP, getValue(props, Notification, false))) { Some( Smtp( @@ -154,6 +159,7 @@ None }, getValue(props, SkinName, "skin-blue"), + getOptionValue(props, UserDefinedCss, None), getValue(props, ShowMailAddress, false), WebHook(getValue(props, WebHookBlockPrivateAddress, false), getSeqValue(props, WebHookWhitelist, "")), Upload( @@ -191,6 +197,7 @@ oidcAuthentication: Boolean, oidc: Option[OIDC], skinName: String, + userDefinedCss: Option[String], showMailAddress: Boolean, webHook: WebHook, upload: Upload @@ -212,10 +219,11 @@ .fold(base)(_ + base.dropWhile(_ != ':')) } - def sshAddress: Option[SshAddress] = ssh.sshHost.collect { - case host if ssh.enabled => - SshAddress(host, ssh.sshPort.getOrElse(DefaultSshPort), "git") - } + def sshAddress: Option[SshAddress] = + ssh.sshHost.collect { + case host if ssh.enabled => + SshAddress(host, ssh.sshPort.getOrElse(DefaultSshPort), "git") + } } case class Ssh( @@ -265,7 +273,7 @@ host: String, port: Int, user: Option[String], - password: Option[String], + password: Option[String] ) case class SshAddress(host: String, port: Int, genericUser: String) @@ -318,6 +326,7 @@ private val OidcClientSecret = "oidc.client_secret" private val OidcJwsAlgorithm = "oidc.jws_algorithm" private val SkinName = "skinName" + private val UserDefinedCss = "userDefinedCss" private val ShowMailAddress = "showMailAddress" private val WebHookBlockPrivateAddress = "webhook.block_private_address" private val WebHookWhitelist = "webhook.whitelist" 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 b90e16b..411463e 100644 --- a/src/main/twirl/gitbucket/core/admin/settings_system.scala.html +++ b/src/main/twirl/gitbucket/core/admin/settings_system.scala.html @@ -94,6 +94,14 @@ + + +
+ +
+ +
+
diff --git a/src/main/twirl/gitbucket/core/main.scala.html b/src/main/twirl/gitbucket/core/main.scala.html index 7260ff3..140aa76 100644 --- a/src/main/twirl/gitbucket/core/main.scala.html +++ b/src/main/twirl/gitbucket/core/main.scala.html @@ -55,6 +55,9 @@ } + @context.settings.userDefinedCss.map { css => + + }
diff --git a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala index 94a7b2e..fff6a78 100644 --- a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala +++ b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala @@ -52,6 +52,7 @@ oidcAuthentication = false, oidc = None, skinName = "skin-blue", + userDefinedCss = None, showMailAddress = false, webHook = SystemSettingsService.WebHook( blockPrivateAddress = false, @@ -114,7 +115,8 @@ } def generateNewIssue(userName: String, repositoryName: String, loginUser: String = "root")( - implicit s: Session + implicit + s: Session ): Int = { dummyService.insertIssue( owner = userName, @@ -130,7 +132,8 @@ } def generateNewPullRequest(base: String, request: String, loginUser: String)( - implicit s: Session + implicit + s: Session ): (Issue, PullRequest) = { implicit val context = Context(createSystemSettings(), None, this.request) val Array(baseUserName, baseRepositoryName, baesBranch) = base.split("/") diff --git a/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala b/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala index a78b0ed..dac7619 100644 --- a/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala +++ b/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala @@ -138,6 +138,7 @@ oidcAuthentication = false, oidc = None, skinName = "skin-blue", + userDefinedCss = None, showMailAddress = false, webHook = WebHook( blockPrivateAddress = false, @@ -157,7 +158,8 @@ class AvatarImageProviderImpl(account: Option[Account]) extends AvatarImageProvider with RequestCache { def toHtml(userName: String, size: Int, mailAddress: String = "", tooltip: Boolean = false)( - implicit context: Context + implicit + context: Context ): Html = getAvatarImageHtml(userName, size, mailAddress, tooltip) override def getAccountByMailAddress(mailAddress: String)(implicit context: Context): Option[Account] = account