Add features (additional filter condition / disable mail resolve) to LDAP authentication.

This commit is contained in:
yjkony
2014-02-28 20:48:09 +09:00
parent 521d15219c
commit 639e7e0b3f
9 changed files with 304 additions and 230 deletions

View File

@@ -56,6 +56,11 @@ trait IndexControllerBase extends ControllerBase {
session.setAttribute(Keys.Session.LoginAccount, account) session.setAttribute(Keys.Session.LoginAccount, account)
updateLastLoginDate(account.userName) updateLastLoginDate(account.userName)
if(AccountUtil.hasLdapDummyMailAddress(account)) {
session.remove(Keys.Session.Redirect)
redirect("/" + account.userName + "/_edit")
}
session.getAndRemove[String](Keys.Session.Redirect).map { redirectUrl => session.getAndRemove[String](Keys.Session.Redirect).map { redirectUrl =>
if(redirectUrl.replaceFirst("/$", "") == request.getContextPath){ if(redirectUrl.replaceFirst("/$", "") == request.getContextPath){
redirect("/") redirect("/")

View File

@@ -7,7 +7,7 @@ import jp.sf.amateras.scalatra.forms._
import org.scalatra.FlashMapSupport import org.scalatra.FlashMapSupport
class SystemSettingsController extends SystemSettingsControllerBase class SystemSettingsController extends SystemSettingsControllerBase
with SystemSettingsService with AccountService with AdminAuthenticator with SystemSettingsService with AccountService with AdminAuthenticator
trait SystemSettingsControllerBase extends ControllerBase with FlashMapSupport { trait SystemSettingsControllerBase extends ControllerBase with FlashMapSupport {
self: SystemSettingsService with AccountService with AdminAuthenticator => self: SystemSettingsService with AccountService with AdminAuthenticator =>
@@ -17,26 +17,28 @@ trait SystemSettingsControllerBase extends ControllerBase with FlashMapSupport {
"gravatar" -> trim(label("Gravatar", boolean())), "gravatar" -> trim(label("Gravatar", boolean())),
"notification" -> trim(label("Notification", boolean())), "notification" -> trim(label("Notification", boolean())),
"smtp" -> optionalIfNotChecked("notification", mapping( "smtp" -> optionalIfNotChecked("notification", mapping(
"host" -> trim(label("SMTP Host", text(required))), "host" -> trim(label("SMTP Host", text(required))),
"port" -> trim(label("SMTP Port", optional(number()))), "port" -> trim(label("SMTP Port", optional(number()))),
"user" -> trim(label("SMTP User", optional(text()))), "user" -> trim(label("SMTP User", optional(text()))),
"password" -> trim(label("SMTP Password", optional(text()))), "password" -> trim(label("SMTP Password", optional(text()))),
"ssl" -> trim(label("Enable SSL", optional(boolean()))), "ssl" -> trim(label("Enable SSL", optional(boolean()))),
"fromAddress" -> trim(label("FROM Address", optional(text()))), "fromAddress" -> trim(label("FROM Address", optional(text()))),
"fromName" -> trim(label("FROM Name", optional(text()))) "fromName" -> trim(label("FROM Name", optional(text())))
)(Smtp.apply)), )(Smtp.apply)),
"ldapAuthentication" -> trim(label("LDAP", boolean())), "ldapAuthentication" -> trim(label("LDAP", boolean())),
"ldap" -> optionalIfNotChecked("ldapAuthentication", mapping( "ldap" -> optionalIfNotChecked("ldapAuthentication", mapping(
"host" -> trim(label("LDAP host", text(required))), "host" -> trim(label("LDAP host", text(required))),
"port" -> trim(label("LDAP port", optional(number()))), "port" -> trim(label("LDAP port", optional(number()))),
"bindDN" -> trim(label("Bind DN", optional(text()))), "bindDN" -> trim(label("Bind DN", optional(text()))),
"bindPassword" -> trim(label("Bind Password", optional(text()))), "bindPassword" -> trim(label("Bind Password", optional(text()))),
"baseDN" -> trim(label("Base DN", text(required))), "baseDN" -> trim(label("Base DN", text(required))),
"userNameAttribute" -> trim(label("User name attribute", text(required))), "userNameAttribute" -> trim(label("User name attribute", text(required))),
"fullNameAttribute" -> trim(label("Full name attribute", optional(text()))), "additionalFilterCondition"-> trim(label("Additional filter condition", optional(text()))),
"mailAttribute" -> trim(label("Mail address attribute", text(required))), "fullNameAttribute" -> trim(label("Full name attribute", optional(text()))),
"tls" -> trim(label("Enable TLS", optional(boolean()))), "mailAttribute" -> trim(label("Mail address attribute", text(required))),
"keystore" -> trim(label("Keystore", optional(text()))) "disableMailResolve" -> trim(label("Disable Mail Resolve", optional(boolean()))),
"tls" -> trim(label("Enable TLS", optional(boolean()))),
"keystore" -> trim(label("Keystore", optional(text())))
)(Ldap.apply)) )(Ldap.apply))
)(SystemSettings.apply) )(SystemSettings.apply)

View File

@@ -39,7 +39,13 @@ trait AccountService {
case Right(ldapUserInfo) => { case Right(ldapUserInfo) => {
// Create or update account by LDAP information // Create or update account by LDAP information
getAccountByUserName(userName, true) match { getAccountByUserName(userName, true) match {
case Some(x) if(!x.isRemoved) => updateAccount(x.copy(mailAddress = ldapUserInfo.mailAddress, fullName = ldapUserInfo.fullName)) case Some(x) if(!x.isRemoved) => {
if(settings.ldap.get.disableMailResolve.getOrElse(false)) {
updateAccount(x.copy(fullName = ldapUserInfo.fullName))
} else {
updateAccount(x.copy(mailAddress = ldapUserInfo.mailAddress, fullName = ldapUserInfo.fullName))
}
}
case Some(x) if(x.isRemoved) => { case Some(x) if(x.isRemoved) => {
logger.info(s"LDAP Authentication Failed: Account is already registered but disabled..") logger.info(s"LDAP Authentication Failed: Account is already registered but disabled..")
defaultAuthentication(userName, password) defaultAuthentication(userName, password)

View File

@@ -31,8 +31,10 @@ trait SystemSettingsService {
ldap.bindPassword.foreach(x => props.setProperty(LdapBindPassword, x)) ldap.bindPassword.foreach(x => props.setProperty(LdapBindPassword, x))
props.setProperty(LdapBaseDN, ldap.baseDN) props.setProperty(LdapBaseDN, ldap.baseDN)
props.setProperty(LdapUserNameAttribute, ldap.userNameAttribute) props.setProperty(LdapUserNameAttribute, ldap.userNameAttribute)
ldap.additionalFilterCondition.foreach(x => props.setProperty(LdapAdditionalFilterCondition, x))
ldap.fullNameAttribute.foreach(x => props.setProperty(LdapFullNameAttribute, x)) ldap.fullNameAttribute.foreach(x => props.setProperty(LdapFullNameAttribute, x))
props.setProperty(LdapMailAddressAttribute, ldap.mailAttribute) props.setProperty(LdapMailAddressAttribute, ldap.mailAttribute)
ldap.disableMailResolve.foreach(x => props.setProperty(LdapDisableMailResolve, x.toString))
ldap.tls.foreach(x => props.setProperty(LdapTls, x.toString)) ldap.tls.foreach(x => props.setProperty(LdapTls, x.toString))
ldap.keystore.foreach(x => props.setProperty(LdapKeystore, x)) ldap.keystore.foreach(x => props.setProperty(LdapKeystore, x))
} }
@@ -72,8 +74,10 @@ trait SystemSettingsService {
getOptionValue(props, LdapBindPassword, None), getOptionValue(props, LdapBindPassword, None),
getValue(props, LdapBaseDN, ""), getValue(props, LdapBaseDN, ""),
getValue(props, LdapUserNameAttribute, ""), getValue(props, LdapUserNameAttribute, ""),
getOptionValue(props, LdapAdditionalFilterCondition, None),
getOptionValue(props, LdapFullNameAttribute, None), getOptionValue(props, LdapFullNameAttribute, None),
getValue(props, LdapMailAddressAttribute, ""), getValue(props, LdapMailAddressAttribute, ""),
getOptionValue[Boolean](props, LdapDisableMailResolve, None),
getOptionValue[Boolean](props, LdapTls, None), getOptionValue[Boolean](props, LdapTls, None),
getOptionValue(props, LdapKeystore, None))) getOptionValue(props, LdapKeystore, None)))
} else { } else {
@@ -89,33 +93,35 @@ object SystemSettingsService {
import scala.reflect.ClassTag import scala.reflect.ClassTag
case class SystemSettings( case class SystemSettings(
allowAccountRegistration: Boolean, allowAccountRegistration: Boolean,
gravatar: Boolean, gravatar: Boolean,
notification: Boolean, notification: Boolean,
smtp: Option[Smtp], smtp: Option[Smtp],
ldapAuthentication: Boolean, ldapAuthentication: Boolean,
ldap: Option[Ldap]) ldap: Option[Ldap])
case class Ldap( case class Ldap(
host: String, host: String,
port: Option[Int], port: Option[Int],
bindDN: Option[String], bindDN: Option[String],
bindPassword: Option[String], bindPassword: Option[String],
baseDN: String, baseDN: String,
userNameAttribute: String, userNameAttribute: String,
fullNameAttribute: Option[String], additionalFilterCondition: Option[String],
mailAttribute: String, fullNameAttribute: Option[String],
tls: Option[Boolean], mailAttribute: String,
keystore: Option[String]) disableMailResolve: Option[Boolean],
tls: Option[Boolean],
keystore: Option[String])
case class Smtp( case class Smtp(
host: String, host: String,
port: Option[Int], port: Option[Int],
user: Option[String], user: Option[String],
password: Option[String], password: Option[String],
ssl: Option[Boolean], ssl: Option[Boolean],
fromAddress: Option[String], fromAddress: Option[String],
fromName: Option[String]) fromName: Option[String])
val DefaultSmtpPort = 25 val DefaultSmtpPort = 25
val DefaultLdapPort = 389 val DefaultLdapPort = 389
@@ -137,8 +143,10 @@ object SystemSettingsService {
private val LdapBindPassword = "ldap.bind_password" private val LdapBindPassword = "ldap.bind_password"
private val LdapBaseDN = "ldap.baseDN" private val LdapBaseDN = "ldap.baseDN"
private val LdapUserNameAttribute = "ldap.username_attribute" private val LdapUserNameAttribute = "ldap.username_attribute"
private val LdapAdditionalFilterCondition = "ldap.additional_filter_condition"
private val LdapFullNameAttribute = "ldap.fullname_attribute" private val LdapFullNameAttribute = "ldap.fullname_attribute"
private val LdapMailAddressAttribute = "ldap.mail_attribute" private val LdapMailAddressAttribute = "ldap.mail_attribute"
private val LdapDisableMailResolve = "ldap.disable_mail_resolve"
private val LdapTls = "ldap.tls" private val LdapTls = "ldap.tls"
private val LdapKeystore = "ldap.keystore" private val LdapKeystore = "ldap.keystore"

View File

@@ -0,0 +1,18 @@
package util
import model.Account
/**
* Utility for account model.
*/
object AccountUtil {
private val LDAP_DUMMY_MAL = "@ldap-devnull"
def hasLdapDummyMailAddress(account: Account): Boolean = {
account.mailAddress.endsWith(LDAP_DUMMY_MAL)
}
def getLdapDummyMailAddress(userName: String): String = {
userName + LDAP_DUMMY_MAL
}
}

View File

@@ -30,7 +30,7 @@ object LDAPUtil {
keystore = ldapSettings.keystore.getOrElse(""), keystore = ldapSettings.keystore.getOrElse(""),
error = "System LDAP authentication failed." error = "System LDAP authentication failed."
){ conn => ){ conn =>
findUser(conn, userName, ldapSettings.baseDN, ldapSettings.userNameAttribute) match { findUser(conn, userName, ldapSettings.baseDN, ldapSettings.userNameAttribute, ldapSettings.additionalFilterCondition) match {
case Some(userDN) => userAuthentication(ldapSettings, userDN, userName, password) case Some(userDN) => userAuthentication(ldapSettings, userDN, userName, password)
case None => Left("User does not exist.") case None => Left("User does not exist.")
} }
@@ -47,20 +47,29 @@ object LDAPUtil {
keystore = ldapSettings.keystore.getOrElse(""), keystore = ldapSettings.keystore.getOrElse(""),
error = "User LDAP Authentication Failed." error = "User LDAP Authentication Failed."
){ conn => ){ conn =>
findMailAddress(conn, userDN, ldapSettings.mailAttribute) match { if(ldapSettings.disableMailResolve.getOrElse(false)) {
case Some(mailAddress) => Right(LDAPUserInfo( Right(LDAPUserInfo(
userName = userName, userName = userName,
fullName = ldapSettings.fullNameAttribute.flatMap { fullNameAttribute => fullName = ldapSettings.fullNameAttribute.flatMap { fullNameAttribute =>
findFullName(conn, userDN, fullNameAttribute) findFullName(conn, userDN, fullNameAttribute)
}.getOrElse(userName), }.getOrElse(userName),
mailAddress = mailAddress)) mailAddress = AccountUtil.getLdapDummyMailAddress(userName)))
case None => Left("Can't find mail address.") } else {
findMailAddress(conn, userDN, ldapSettings.mailAttribute) match {
case Some(mailAddress) => Right(LDAPUserInfo(
userName = userName,
fullName = ldapSettings.fullNameAttribute.flatMap { fullNameAttribute =>
findFullName(conn, userDN, fullNameAttribute)
}.getOrElse(userName),
mailAddress = mailAddress))
case None => Left("Can't find mail address.")
}
} }
} }
} }
private def bind[A](host: String, port: Int, dn: String, password: String, tls: Boolean, keystore: String, error: String) private def bind[A](host: String, port: Int, dn: String, password: String, tls: Boolean, keystore: String, error: String)
(f: LDAPConnection => Either[String, A]): Either[String, A] = { (f: LDAPConnection => Either[String, A]): Either[String, A] = {
if (tls) { if (tls) {
// Dynamically set Sun as the security provider // Dynamically set Sun as the security provider
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()) Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider())
@@ -105,7 +114,7 @@ object LDAPUtil {
/** /**
* Search a specified user and returns userDN if exists. * Search a specified user and returns userDN if exists.
*/ */
private def findUser(conn: LDAPConnection, userName: String, baseDN: String, userNameAttribute: String): Option[String] = { private def findUser(conn: LDAPConnection, userName: String, baseDN: String, userNameAttribute: String, additionalFilterCondition: Option[String]): Option[String] = {
@tailrec @tailrec
def getEntries(results: LDAPSearchResults, entries: List[Option[LDAPEntry]] = Nil): List[LDAPEntry] = { def getEntries(results: LDAPSearchResults, entries: List[Option[LDAPEntry]] = Nil): List[LDAPEntry] = {
if(results.hasMore){ if(results.hasMore){
@@ -118,7 +127,13 @@ object LDAPUtil {
entries.flatten entries.flatten
} }
} }
getEntries(conn.search(baseDN, LDAPConnection.SCOPE_SUB, userNameAttribute + "=" + userName, null, false)).collectFirst {
val filterCond = additionalFilterCondition.getOrElse("") match {
case "" => userNameAttribute + "=" + userName
case x => "(&(" + x + ")(" + userNameAttribute + "=" + userName + "))"
}
getEntries(conn.search(baseDN, LDAPConnection.SCOPE_SUB, filterCond, null, false)).collectFirst {
case x => x.getDN case x => x.getDN
} }
} }

View File

@@ -27,7 +27,7 @@ trait Notifier extends RepositoryService with AccountService with IssuesService
) )
.distinct .distinct
.withFilter ( _ != context.loginAccount.get.userName ) // the operation in person is excluded .withFilter ( _ != context.loginAccount.get.userName ) // the operation in person is excluded
.foreach ( getAccountByUserName(_) filterNot (_.isGroupAccount) foreach (x => notify(x.mailAddress)) ) .foreach ( getAccountByUserName(_) filterNot (_.isGroupAccount) filterNot (AccountUtil.hasLdapDummyMailAddress(_)) foreach (x => notify(x.mailAddress)) )
} }

View File

@@ -1,13 +1,17 @@
@(account: Option[model.Account], info: Option[Any])(implicit context: app.Context) @(account: Option[model.Account], info: Option[Any])(implicit context: app.Context)
@import context._ @import context._
@import view.helpers._ @import view.helpers._
@import util.AccountUtil
@html.main((if(account.isDefined) "Edit your profile" else "Create your account")){ @html.main((if(account.isDefined) "Edit your profile" else "Create your account")){
@helper.html.information(info)
@if(account.isDefined && AccountUtil.hasLdapDummyMailAddress(account.get)) {
<div class="alert alert-danger">Please register your mail address.</div>
}
@if(account.isDefined){ @if(account.isDefined){
<h3>Edit your profile</h3> <h3>Edit your profile</h3>
} else { } else {
<h3>Create your account</h3> <h3>Create your account</h3>
} }
@helper.html.information(info)
<form action="@if(account.isDefined){@url(account.get.userName)/_edit}else{@path/register}" method="POST" validate="true"> <form action="@if(account.isDefined){@url(account.get.userName)/_edit}else{@path/register}" method="POST" validate="true">
<div class="row-fluid"> <div class="row-fluid">
<div class="span6"> <div class="span6">
@@ -38,7 +42,7 @@
</fieldset> </fieldset>
<fieldset> <fieldset>
<label for="mailAddress" class="strong">Mail Address:</label> <label for="mailAddress" class="strong">Mail Address:</label>
<input type="text" name="mailAddress" id="mailAddress" value="@account.map(_.mailAddress)"/> <input type="text" name="mailAddress" id="mailAddress" value="@if(account.isDefined && !AccountUtil.hasLdapDummyMailAddress(account.get)){@account.map(_.mailAddress)}"/>
<span id="error-mailAddress" class="error"></span> <span id="error-mailAddress" class="error"></span>
</fieldset> </fieldset>
<fieldset> <fieldset>
@@ -60,7 +64,9 @@
<a href="@path/@account.get.userName/_delete" class="btn btn-danger" id="delete">Delete account</a> <a href="@path/@account.get.userName/_delete" class="btn btn-danger" id="delete">Delete account</a>
</div> </div>
<input type="submit" class="btn btn-success" value="Save"/> <input type="submit" class="btn btn-success" value="Save"/>
@if(!AccountUtil.hasLdapDummyMailAddress(account.get)){
<a href="@url(account.get.userName)" class="btn">Cancel</a> <a href="@url(account.get.userName)" class="btn">Cancel</a>
}
} else { } else {
<input type="submit" class="btn btn-success" value="Create account"/> <input type="submit" class="btn btn-success" value="Create account"/>
} }

View File

@@ -3,191 +3,205 @@
@import util.Directory._ @import util.Directory._
@import view.helpers._ @import view.helpers._
@html.main("System Settings"){ @html.main("System Settings"){
@menu("system"){ @menu("system"){
@helper.html.information(info) @helper.html.information(info)
<form action="@path/admin/system" method="POST" validate="true"> <form action="@path/admin/system" method="POST" validate="true">
<div class="box"> <div class="box">
<div class="box-header">System Settings</div> <div class="box-header">System Settings</div>
<div class="box-content"> <div class="box-content">
<!--====================================================================--> <!--====================================================================-->
<!-- GITBUCKET_HOME --> <!-- GITBUCKET_HOME -->
<!--====================================================================--> <!--====================================================================-->
<label class="strong">GITBUCKET_HOME</label> <label class="strong">GITBUCKET_HOME</label>
@GitBucketHome @GitBucketHome
<!--====================================================================--> <!--====================================================================-->
<!-- Account registration --> <!-- Account registration -->
<!--====================================================================--> <!--====================================================================-->
<hr> <hr>
<label class="strong">Account registration</label> <label class="strong">Account registration</label>
<fieldset> <fieldset>
<label class="radio"> <label class="radio">
<input type="radio" name="allowAccountRegistration" value="true"@if(settings.allowAccountRegistration){ checked}> <input type="radio" name="allowAccountRegistration" value="true"@if(settings.allowAccountRegistration){ checked}>
<span class="strong">Allow</span> - Users can create accounts by themselves. <span class="strong">Allow</span> - Users can create accounts by themselves.
</label>
<label class="radio">
<input type="radio" name="allowAccountRegistration" value="false"@if(!settings.allowAccountRegistration){ checked}>
<span class="strong">Deny</span> - Only administrators can create accounts.
</label>
</fieldset>
<!--====================================================================-->
<!-- Services -->
<!--====================================================================-->
<hr>
<label class="strong">Services</label>
<fieldset>
<label class="checkbox">
<input type="checkbox" name="gravatar"@if(settings.gravatar){ checked}/>
Use Gravatar for Profile-Images
</label>
</fieldset>
<!--====================================================================-->
<!-- Authentication -->
<!--====================================================================-->
<hr>
<label class="strong">Authentication</label>
<fieldset>
<label class="checkbox">
<input type="checkbox" id="ldapAuthentication" name="ldapAuthentication"@if(settings.ldap){ checked}/>
LDAP
</label>
</fieldset>
<div class="form-horizontal ldap">
<div class="control-group">
<label class="control-label" for="ldapHost">LDAP Host</label>
<div class="controls">
<input type="text" id="ldapHost" name="ldap.host" value="@settings.ldap.map(_.host)"/>
<span id="error-ldap_host" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapPort">LDAP Port</label>
<div class="controls">
<input type="text" id="ldapPort" name="ldap.port" class="input-mini" value="@settings.ldap.map(_.port)"/>
<span id="error-ldap_port" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBindDN">Bind DN</label>
<div class="controls">
<input type="text" id="ldapBindDN" name="ldap.bindDN" value="@settings.ldap.map(_.bindDN)"/>
<span id="error-ldap_bindDN" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBindPassword">Bind Password</label>
<div class="controls">
<input type="password" id="ldapBindPassword" name="ldap.bindPassword" value="@settings.ldap.map(_.bindPassword)"/>
<span id="error-ldap_bindPassword" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBaseDN">Base DN</label>
<div class="controls">
<input type="text" id="ldapBaseDN" name="ldap.baseDN" value="@settings.ldap.map(_.baseDN)"/>
<span id="error-ldap_baseDN" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapUserNameAttribute">User name attribute</label>
<div class="controls">
<input type="text" id="ldapUserNameAttribute" name="ldap.userNameAttribute" value="@settings.ldap.map(_.userNameAttribute)"/>
<span id="error-ldap_userNameAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapFullNameAttribute">Full name attribute</label>
<div class="controls">
<input type="text" id="ldapFullNameAttribute" name="ldap.fullNameAttribute" value="@settings.ldap.map(_.fullNameAttribute)"/>
<span id="error-ldap_fullNameAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapMailAttribute">Mail address attribute</label>
<div class="controls">
<input type="text" id="ldapMailAttribute" name="ldap.mailAttribute" value="@settings.ldap.map(_.mailAttribute)"/>
<span id="error-ldap_mailAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="ldap.tls"@if(settings.ldap.flatMap(_.tls).getOrElse(false)){ checked}/> Enable TLS
</label> </label>
</div> <label class="radio">
</div> <input type="radio" name="allowAccountRegistration" value="false"@if(!settings.allowAccountRegistration){ checked}>
<div class="control-group"> <span class="strong">Deny</span> - Only administrators can create accounts.
<label class="control-label" for="ldapBindDN">Keystore</label>
<div class="controls">
<input type="text" id="ldapKeystore" name="ldap.keystore" value="@settings.ldap.map(_.keystore)"/>
<span id="error-ldap_keystore" class="error"></span>
</div>
</div>
</div>
<!--====================================================================-->
<!-- Notification email -->
<!--====================================================================-->
<hr>
<label class="strong">Notification email</label>
<fieldset>
<label class="checkbox">
<input type="checkbox" id="notification" name="notification"@if(settings.notification){ checked}/>
Send notifications
</label>
</fieldset>
<div class="form-horizontal notification">
<div class="control-group">
<label class="control-label" for="smtpHost">SMTP Host</label>
<div class="controls">
<input type="text" id="smtpHost" name="smtp.host" value="@settings.smtp.map(_.host)"/>
<span id="error-smtp_host" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="smtpPort">SMTP Port</label>
<div class="controls">
<input type="text" id="smtpPort" name="smtp.port" class="input-mini" value="@settings.smtp.map(_.port)"/>
<span id="error-smtp_port" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="smtpUser">SMTP User</label>
<div class="controls">
<input type="text" id="smtpUser" name="smtp.user" value="@settings.smtp.map(_.user)"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="smtpPassword">SMTP Password</label>
<div class="controls">
<input type="password" id="smtpPassword" name="smtp.password" value="@settings.smtp.map(_.password)"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="smtp.ssl"@if(settings.smtp.flatMap(_.ssl).getOrElse(false)){ checked}/> Enable SSL
</label> </label>
</div> </fieldset>
<!--====================================================================-->
<!-- Services -->
<!--====================================================================-->
<hr>
<label class="strong">Services</label>
<fieldset>
<label class="checkbox">
<input type="checkbox" name="gravatar"@if(settings.gravatar){ checked}/>
Use Gravatar for Profile-Images
</label>
</fieldset>
<!--====================================================================-->
<!-- Authentication -->
<!--====================================================================-->
<hr>
<label class="strong">Authentication</label>
<fieldset>
<label class="checkbox">
<input type="checkbox" id="ldapAuthentication" name="ldapAuthentication"@if(settings.ldap){ checked}/>
LDAP
</label>
</fieldset>
<div class="form-horizontal ldap">
<div class="control-group">
<label class="control-label" for="ldapHost">LDAP Host</label>
<div class="controls">
<input type="text" id="ldapHost" name="ldap.host" value="@settings.ldap.map(_.host)"/>
<span id="error-ldap_host" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapPort">LDAP Port</label>
<div class="controls">
<input type="text" id="ldapPort" name="ldap.port" class="input-mini" value="@settings.ldap.map(_.port)"/>
<span id="error-ldap_port" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBindDN">Bind DN</label>
<div class="controls">
<input type="text" id="ldapBindDN" name="ldap.bindDN" value="@settings.ldap.map(_.bindDN)"/>
<span id="error-ldap_bindDN" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBindPassword">Bind Password</label>
<div class="controls">
<input type="password" id="ldapBindPassword" name="ldap.bindPassword" value="@settings.ldap.map(_.bindPassword)"/>
<span id="error-ldap_bindPassword" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBaseDN">Base DN</label>
<div class="controls">
<input type="text" id="ldapBaseDN" name="ldap.baseDN" value="@settings.ldap.map(_.baseDN)"/>
<span id="error-ldap_baseDN" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapUserNameAttribute">User name attribute</label>
<div class="controls">
<input type="text" id="ldapUserNameAttribute" name="ldap.userNameAttribute" value="@settings.ldap.map(_.userNameAttribute)"/>
<span id="error-ldap_userNameAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapAdditionalFilterCondition">Additional filter condition</label>
<div class="controls">
<input type="text" id="ldapAdditionalFilterCondition" name="ldap.additionalFilterCondition" value="@settings.ldap.map(_.additionalFilterCondition)"/>
<span id="error-ldap_additionalFilterCondition" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapFullNameAttribute">Full name attribute</label>
<div class="controls">
<input type="text" id="ldapFullNameAttribute" name="ldap.fullNameAttribute" value="@settings.ldap.map(_.fullNameAttribute)"/>
<span id="error-ldap_fullNameAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapMailAttribute">Mail address attribute</label>
<div class="controls">
<input type="text" id="ldapMailAttribute" name="ldap.mailAttribute" value="@settings.ldap.map(_.mailAttribute)"/>
<span id="error-ldap_mailAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="ldap.disableMailResolve"@if(settings.ldap.flatMap(_.disableMailResolve).getOrElse(false)){ checked}/> Disable Mail Resolve
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="ldap.tls"@if(settings.ldap.flatMap(_.tls).getOrElse(false)){ checked}/> Enable TLS
</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBindDN">Keystore</label>
<div class="controls">
<input type="text" id="ldapKeystore" name="ldap.keystore" value="@settings.ldap.map(_.keystore)"/>
<span id="error-ldap_keystore" class="error"></span>
</div>
</div>
</div> </div>
<div class="control-group"> <!--====================================================================-->
<label class="control-label" for="fromAddress">FROM Address</label> <!-- Notification email -->
<div class="controls"> <!--====================================================================-->
<input type="text" id="fromAddress" name="smtp.fromAddress" value="@settings.smtp.map(_.fromAddress)"/> <hr>
</div> <label class="strong">Notification email</label>
<fieldset>
<label class="checkbox">
<input type="checkbox" id="notification" name="notification"@if(settings.notification){ checked}/>
Send notifications
</label>
</fieldset>
<div class="form-horizontal notification">
<div class="control-group">
<label class="control-label" for="smtpHost">SMTP Host</label>
<div class="controls">
<input type="text" id="smtpHost" name="smtp.host" value="@settings.smtp.map(_.host)"/>
<span id="error-smtp_host" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="smtpPort">SMTP Port</label>
<div class="controls">
<input type="text" id="smtpPort" name="smtp.port" class="input-mini" value="@settings.smtp.map(_.port)"/>
<span id="error-smtp_port" class="error"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="smtpUser">SMTP User</label>
<div class="controls">
<input type="text" id="smtpUser" name="smtp.user" value="@settings.smtp.map(_.user)"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="smtpPassword">SMTP Password</label>
<div class="controls">
<input type="password" id="smtpPassword" name="smtp.password" value="@settings.smtp.map(_.password)"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="smtp.ssl"@if(settings.smtp.flatMap(_.ssl).getOrElse(false)){ checked}/> Enable SSL
</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="fromAddress">FROM Address</label>
<div class="controls">
<input type="text" id="fromAddress" name="smtp.fromAddress" value="@settings.smtp.map(_.fromAddress)"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="fromName">FROM Name</label>
<div class="controls">
<input type="text" id="fromName" name="smtp.fromName" value="@settings.smtp.map(_.fromName)"/>
</div>
</div>
</div> </div>
<div class="control-group">
<label class="control-label" for="fromName">FROM Name</label>
<div class="controls">
<input type="text" id="fromName" name="smtp.fromName" value="@settings.smtp.map(_.fromName)"/>
</div>
</div>
</div>
</div> </div>
</div> </div>
<fieldset> <fieldset>
<input type="submit" class="btn btn-success" value="Apply changes"/> <input type="submit" class="btn btn-success" value="Apply changes"/>
</fieldset> </fieldset>
</form> </form>
} }
} }
<script> <script>
$(function(){ $(function(){