diff --git a/src/main/scala/app/AccountController.scala b/src/main/scala/app/AccountController.scala index b32d5df..5bea0b4 100644 --- a/src/main/scala/app/AccountController.scala +++ b/src/main/scala/app/AccountController.scala @@ -9,12 +9,10 @@ import org.apache.commons.io.FileUtils class AccountController extends AccountControllerBase - with SystemSettingsService with AccountService with RepositoryService with ActivityService - with OneselfAuthenticator + with AccountService with RepositoryService with ActivityService with OneselfAuthenticator trait AccountControllerBase extends AccountManagementControllerBase with FlashMapSupport { - self: SystemSettingsService with AccountService with RepositoryService with ActivityService - with OneselfAuthenticator => + self: AccountService with RepositoryService with ActivityService with OneselfAuthenticator => case class AccountNewForm(userName: String, password: String, fullName: String, mailAddress: String, url: Option[String], fileId: Option[String]) diff --git a/src/main/scala/app/ControllerBase.scala b/src/main/scala/app/ControllerBase.scala index a026a18..f80d15a 100644 --- a/src/main/scala/app/ControllerBase.scala +++ b/src/main/scala/app/ControllerBase.scala @@ -10,8 +10,7 @@ import jp.sf.amateras.scalatra.forms._ import org.apache.commons.io.FileUtils import model.Account -import scala.Some -import service.AccountService +import service.{SystemSettingsService, AccountService} import javax.servlet.http.{HttpServletResponse, HttpSession, HttpServletRequest} import java.text.SimpleDateFormat import javax.servlet.{FilterChain, ServletResponse, ServletRequest} @@ -21,7 +20,7 @@ * Provides generic features for controller implementations. */ abstract class ControllerBase extends ScalatraFilter - with ClientSideValidationFormSupport with JacksonJsonSupport with I18nSupport with Validations { + with ClientSideValidationFormSupport with JacksonJsonSupport with I18nSupport with Validations with SystemSettingsService { implicit val jsonFormats = DefaultFormats @@ -58,8 +57,9 @@ /** * Returns the context object for the request. */ - implicit def context: Context = Context(servletContext.getContextPath, LoginAccount, currentURL, request) + implicit def context: Context = Context(servletContext.getContextPath, LoginAccount, request) + // TODO This method should be remvoved. private def currentURL: String = defining(request.getQueryString){ queryString => request.getRequestURI + (if(queryString != null) "?" + queryString else "") } @@ -107,13 +107,16 @@ if(request.getMethod.toUpperCase == "POST"){ org.scalatra.Unauthorized(redirect("/signin")) } else { + // TODO This URL may not be same as the front URL... org.scalatra.Unauthorized(redirect("/signin?redirect=" + StringUtil.urlEncode(currentURL))) } } } - protected def baseUrl = defining(request.getRequestURL.toString){ url => - url.substring(0, url.length - (request.getRequestURI.length - request.getContextPath.length)) + protected def baseUrl = loadSystemSettings().baseUrl.getOrElse { + defining(request.getRequestURL.toString){ url => + url.substring(0, url.length - (request.getRequestURI.length - request.getContextPath.length)) + } } } @@ -121,13 +124,7 @@ /** * Context object for the current request. */ -case class Context(path: String, loginAccount: Option[Account], currentUrl: String, request: HttpServletRequest){ - - def redirectUrl = if(request.getParameter("redirect") != null){ - request.getParameter("redirect") - } else { - currentUrl - } +case class Context(path: String, loginAccount: Option[Account], request: HttpServletRequest){ /** * Get object from cache. diff --git a/src/main/scala/app/IndexController.scala b/src/main/scala/app/IndexController.scala index 2f5f689..2ee96bd 100644 --- a/src/main/scala/app/IndexController.scala +++ b/src/main/scala/app/IndexController.scala @@ -6,11 +6,10 @@ import jp.sf.amateras.scalatra.forms._ class IndexController extends IndexControllerBase - with RepositoryService with SystemSettingsService with ActivityService with AccountService -with UsersAuthenticator + with RepositoryService with ActivityService with AccountService with UsersAuthenticator trait IndexControllerBase extends ControllerBase { - self: RepositoryService with SystemSettingsService with ActivityService with AccountService with UsersAuthenticator => + self: RepositoryService with ActivityService with AccountService with UsersAuthenticator => case class SignInForm(userName: String, password: String) diff --git a/src/main/scala/app/SearchController.scala b/src/main/scala/app/SearchController.scala index 99ea743..ab091cf 100644 --- a/src/main/scala/app/SearchController.scala +++ b/src/main/scala/app/SearchController.scala @@ -6,13 +6,10 @@ import jp.sf.amateras.scalatra.forms._ class SearchController extends SearchControllerBase -with RepositoryService with AccountService with SystemSettingsService with ActivityService -with RepositorySearchService with IssuesService -with ReferrerAuthenticator + with RepositoryService with AccountService with ActivityService with RepositorySearchService with IssuesService with ReferrerAuthenticator trait SearchControllerBase extends ControllerBase { self: RepositoryService - with SystemSettingsService with ActivityService with RepositorySearchService - with ReferrerAuthenticator => + with ActivityService with RepositorySearchService with ReferrerAuthenticator => val searchForm = mapping( "query" -> trim(text(required)), diff --git a/src/main/scala/app/SystemSettingsController.scala b/src/main/scala/app/SystemSettingsController.scala index d6dd787..08231b6 100644 --- a/src/main/scala/app/SystemSettingsController.scala +++ b/src/main/scala/app/SystemSettingsController.scala @@ -13,6 +13,7 @@ self: SystemSettingsService with AccountService with AdminAuthenticator => private val form = mapping( + "baseUrl" -> trim(label("Base URL", optional(text()))), "allowAccountRegistration" -> trim(label("Account registration", boolean())), "gravatar" -> trim(label("Gravatar", boolean())), "notification" -> trim(label("Notification", boolean())), diff --git a/src/main/scala/service/SystemSettingsService.scala b/src/main/scala/service/SystemSettingsService.scala index 5514cbe..de7a966 100644 --- a/src/main/scala/service/SystemSettingsService.scala +++ b/src/main/scala/service/SystemSettingsService.scala @@ -8,6 +8,7 @@ def saveSystemSettings(settings: SystemSettings): Unit = { defining(new java.util.Properties()){ props => + settings.baseUrl.foreach(props.setProperty(BaseURL, _)) props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString) props.setProperty(Gravatar, settings.gravatar.toString) props.setProperty(Notification, settings.notification.toString) @@ -48,6 +49,7 @@ props.load(new java.io.FileInputStream(GitBucketConf)) } SystemSettings( + getOptionValue(props, BaseURL, None), getValue(props, AllowAccountRegistration, false), getValue(props, Gravatar, true), getValue(props, Notification, false), @@ -89,6 +91,7 @@ import scala.reflect.ClassTag case class SystemSettings( + baseUrl: Option[String], allowAccountRegistration: Boolean, gravatar: Boolean, notification: Boolean, @@ -120,6 +123,7 @@ val DefaultSmtpPort = 25 val DefaultLdapPort = 389 + private val BaseURL = "base_url" private val AllowAccountRegistration = "allow_account_registration" private val Gravatar = "gravatar" private val Notification = "notification" diff --git a/src/main/twirl/admin/system.scala.html b/src/main/twirl/admin/system.scala.html index 1ccab70..6594e29 100644 --- a/src/main/twirl/admin/system.scala.html +++ b/src/main/twirl/admin/system.scala.html @@ -15,6 +15,21 @@ @GitBucketHome + + +
+ +
+
+ +
+
+

+ The base URL is used for redirect, notification email, git repository URL box and more. + If the base URL is empty, GitBucket generates URL from request information. + You can use this property to adjust URL difference between the reverse proxy and GitBucket. +

+
diff --git a/src/main/twirl/main.scala.html b/src/main/twirl/main.scala.html index 592238a..7ec9842 100644 --- a/src/main/twirl/main.scala.html +++ b/src/main/twirl/main.scala.html @@ -61,7 +61,7 @@ } } else { - Sign in + Sign in } @@ -76,6 +76,7 @@ $('#search').submit(function(){ return $.trim($(this).find('input[name=query]').val()) != ''; }); + $('#signin').attr('href', '@path/signin?redirect=' + encodeURIComponent(location.pathname + location.search + location.hash)); });