Add System Settings page.

This commit is contained in:
takezoe
2013-06-28 13:45:31 +09:00
parent a5cb3bc9cd
commit 00ad0c1745
9 changed files with 195 additions and 70 deletions

View File

@@ -6,7 +6,8 @@ class ScalatraBootstrap extends LifeCycle {
override def init(context: ServletContext) { override def init(context: ServletContext) {
context.mount(new IndexController, "/") context.mount(new IndexController, "/")
context.mount(new SignInController, "/*") context.mount(new SignInController, "/*")
context.mount(new UsersController, "/*") context.mount(new UserManagementController, "/*")
context.mount(new SystemSettingsController, "/*")
context.mount(new CreateRepositoryController, "/*") context.mount(new CreateRepositoryController, "/*")
context.mount(new AccountController, "/*") context.mount(new AccountController, "/*")
context.mount(new RepositoryViewerController, "/*") context.mount(new RepositoryViewerController, "/*")

View File

@@ -0,0 +1,30 @@
package app
import service.{AccountService, SystemSettingsService}
import SystemSettingsService._
import util.AdminOnlyAuthenticator
import jp.sf.amateras.scalatra.forms._
class SystemSettingsController extends SystemSettingsControllerBase
with SystemSettingsService with AccountService with AdminOnlyAuthenticator
trait SystemSettingsControllerBase extends ControllerBase {
self: SystemSettingsService with AccountService with AdminOnlyAuthenticator =>
private case class SystemSettingsForm(allowAccountRegistration: Boolean)
private val form = mapping(
"allowAccountRegistration" -> trim(label("Account registration", boolean()))
)(SystemSettingsForm.apply)
get("/admin/system")(adminOnly {
admin.html.system(loadSystemSettings())
})
post("/admin/system", form)(adminOnly { form =>
saveSystemSettings(SystemSettings(form.allowAccountRegistration))
redirect("/admin/system")
})
}

View File

@@ -5,9 +5,9 @@ import service._
import util.AdminOnlyAuthenticator import util.AdminOnlyAuthenticator
import jp.sf.amateras.scalatra.forms._ import jp.sf.amateras.scalatra.forms._
class UsersController extends UsersControllerBase with AccountService with AdminOnlyAuthenticator class UserManagementController extends UserManagementControllerBase with AccountService with AdminOnlyAuthenticator
trait UsersControllerBase extends ControllerBase { self: AccountService with AdminOnlyAuthenticator => trait UserManagementControllerBase extends ControllerBase { self: AccountService with AdminOnlyAuthenticator =>
case class UserForm(userName: String, password: String, mailAddress: String, isAdmin: Boolean, url: Option[String]) case class UserForm(userName: String, password: String, mailAddress: String, isAdmin: Boolean, url: Option[String])

View File

@@ -0,0 +1,40 @@
package service
import util.Directory._
import SystemSettingsService._
trait SystemSettingsService {
def saveSystemSettings(settings: SystemSettings): Unit = {
val props = new java.util.Properties()
props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString)
props.store(new java.io.FileOutputStream(GitBucketConf), null)
}
def loadSystemSettings(): SystemSettings = {
val props = new java.util.Properties()
if(GitBucketConf.exists){
props.load(new java.io.FileInputStream(GitBucketConf))
}
SystemSettings(getBoolean(props, "allow_account_registration"))
}
}
object SystemSettingsService {
case class SystemSettings(allowAccountRegistration: Boolean)
private val AllowAccountRegistration = "allow_account_registration"
private def getBoolean(props: java.util.Properties, key: String, default: Boolean = false): Boolean = {
val value = props.getProperty(key)
if(value == null || value.isEmpty){
default
} else {
value.toBoolean
}
}
}

View File

@@ -10,6 +10,8 @@ import org.eclipse.jgit.lib.Ref
object Directory { object Directory {
val GitBucketHome = new File(System.getProperty("user.home"), "gitbucket").getAbsolutePath val GitBucketHome = new File(System.getProperty("user.home"), "gitbucket").getAbsolutePath
val GitBucketConf = new File(GitBucketHome, "gitbucket.conf")
val RepositoryHome = "%s/repositories".format(GitBucketHome) val RepositoryHome = "%s/repositories".format(GitBucketHome)

View File

@@ -0,0 +1,17 @@
@(active: String)(body: Html)(implicit context: app.Context)
@import context._
<div class="row-fluid">
<div class="span3">
<ul class="nav nav-tabs nav-stacked">
<li@if(active=="users"){ class="active"}>
<a href="@path/admin/users">User Management</a>
</li>
<li@if(active=="system"){ class="active"}>
<a href="@path/admin/system">System Settings</a>
</li>
</ul>
</div>
<div class="span9">
@body
</div>
</div>

View File

@@ -0,0 +1,28 @@
@(settings: service.SystemSettingsService.SystemSettings)(implicit context: app.Context)
@import context._
@import view.helpers._
@html.main("System Settings"){
@menu("system"){
<form action="@path/admin/system" method="POST" validate="true">
<div class="box">
<div class="box-header">System Settings</div>
<div class="box-content">
<label><strong>Account registration</strong></label>
<fieldset>
<label>
<input type="radio" name="allowAccountRegistration" value="true"@if(settings.allowAccountRegistration){ checked}>
<strong>Allow</strong> - Users can create account by themselves.
</label>
<label>
<input type="radio" name="allowAccountRegistration" value="false"@if(!settings.allowAccountRegistration){ checked}>
<strong>Deny</strong> - Only administrators can create account.
</label>
</fieldset>
</div>
</div>
<fieldset>
<input type="submit" class="btn btn-success" value="Apply changes"/>
</fieldset>
</form>
}
}

View File

@@ -1,39 +1,41 @@
@(account: Option[model.Account])(implicit context: app.Context) @(account: Option[model.Account])(implicit context: app.Context)
@import context._ @import context._
@html.main(if(account.isEmpty) "New User" else "Update User"){ @html.main(if(account.isEmpty) "New User" else "Update User"){
<form method="POST" action="@if(account.isEmpty){@path/admin/users/_new} else {@path/admin/users/@account.get.userName/_edit}" validate="true"> @menu("users"){
<fieldset> <form method="POST" action="@if(account.isEmpty){@path/admin/users/_new} else {@path/admin/users/@account.get.userName/_edit}" validate="true">
<label for="userName"><strong>Username</strong></label> <fieldset>
<input type="text" name="userName" id="userName" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/> <label for="userName"><strong>Username</strong></label>
<span id="error-userName" class="error"></span> <input type="text" name="userName" id="userName" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/>
</fieldset> <span id="error-userName" class="error"></span>
<fieldset> </fieldset>
<label for="password"><strong>Password</strong></label> <fieldset>
<input type="password" name="password" id="password" value="@account.map(_.password)"/> <label for="password"><strong>Password</strong></label>
<span id="error-password" class="error"></span> <input type="password" name="password" id="password" value="@account.map(_.password)"/>
</fieldset> <span id="error-password" class="error"></span>
<fieldset> </fieldset>
<label for="mailAddress"><strong>Mail Address</strong></label> <fieldset>
<input type="text" name="mailAddress" id="mailAddress" value="@account.map(_.mailAddress)"/> <label for="mailAddress"><strong>Mail Address</strong></label>
<span id="error-mailAddress" class="error"></span> <input type="text" name="mailAddress" id="mailAddress" value="@account.map(_.mailAddress)"/>
</fieldset> <span id="error-mailAddress" class="error"></span>
<fieldset> </fieldset>
<label><strong>User Type</strong></label> <fieldset>
<label for="userType_Normal"> <label><strong>User Type</strong></label>
<input type="radio" name="isAdmin" id="userType_Normal" value="false"@if(account.isEmpty || !account.get.isAdmin){ checked}/> Normal <label for="userType_Normal">
</label> <input type="radio" name="isAdmin" id="userType_Normal" value="false"@if(account.isEmpty || !account.get.isAdmin){ checked}/> Normal
<label for="userType_Admin"> </label>
<input type="radio" name="isAdmin" id="userType_Admin" value="true"@if(account.isDefined && account.get.isAdmin){ checked}/> Administrator <label for="userType_Admin">
</label> <input type="radio" name="isAdmin" id="userType_Admin" value="true"@if(account.isDefined && account.get.isAdmin){ checked}/> Administrator
</fieldset> </label>
<fieldset> </fieldset>
<label><strong>URL (Optional)</strong></label> <fieldset>
<input type="text" name="url" id="url" style="width: 400px;" value="@account.map(_.url)"/> <label><strong>URL (Optional)</strong></label>
<span id="error-url" class="error"></span> <input type="text" name="url" id="url" style="width: 400px;" value="@account.map(_.url)"/>
</fieldset> <span id="error-url" class="error"></span>
<fieldset> </fieldset>
<input type="submit" class="btn btn-success" value="@if(account.isEmpty){Create User} else {Update User}"/> <fieldset>
<a href="@path/admin/users" class="btn">Cancel</a> <input type="submit" class="btn btn-success" value="@if(account.isEmpty){Create User} else {Update User}"/>
</fieldset> <a href="@path/admin/users" class="btn">Cancel</a>
</form> </fieldset>
</form>
}
} }

View File

@@ -1,36 +1,41 @@
@(users: List[model.Account])(implicit context: app.Context) @(users: List[model.Account])(implicit context: app.Context)
@import context._ @import context._
@import view.helpers @import view.helpers._
@html.main("Manage Users"){ @html.main("Manage Users"){
<div style="text-align: right; margin-bottom: 4px;"> @menu("users"){
<a href="@path/admin/users/_new" class="btn">New User</a> <div style="text-align: right; margin-bottom: 4px;">
</div> <a href="@path/admin/users/_new" class="btn">New User</a>
<table class="table table-borderd table-hover"> </div>
<tr> <table class="table table-bordered table-hover">
<th>Username</th> @users.map { account =>
<th>Mail Address</th> <tr>
<th>Type</th> <td>
<th>URL</th> <div class="pull-right">
<th>Registered</th> <a href="@path/admin/users/@account.userName/_edit">Edit</a>
<th>Updated</th> </div>
<th>Last Login</th> <div class="strong">
</tr> <a href="@url(account.userName)">@account.userName</a>
@users.map { account => @if(account.isAdmin){
<tr> (Administrator)
<td><a href="@path/admin/users/@account.userName/_edit">@account.userName</a></td> } else {
<td>@account.mailAddress</td> (Normal)
<td> }
@if(account.isAdmin){ </div>
Administrator <div>
} else { <hr>
Normal <i class="icon-envelope"></i> @account.mailAddress
} @account.url.map { url =>
</td> <i class="icon-home"></i> @url
<td>@account.url</td> }
<td>@helpers.datetime(account.registeredDate)</td> </div>
<td>@helpers.datetime(account.updatedDate)</td> <div>
<td>@account.lastLoginDate.map(helpers.datetime)</td> <span class="muted">Registered:</span> @datetime(account.registeredDate)
</tr> <span class="muted">Updated:</span> @datetime(account.updatedDate)
} <span class="muted">Last Login:</span> @account.lastLoginDate.map(datetime)
</table> </div>
</td>
</tr>
}
</table>
}
} }