Skip to content

Commit

Permalink
Finish feature-complete-ldap-login
Browse files Browse the repository at this point in the history
  • Loading branch information
msarti committed Mar 16, 2014
2 parents ff88f2b + 55aaab8 commit f7421ed
Show file tree
Hide file tree
Showing 17 changed files with 295 additions and 88 deletions.
12 changes: 12 additions & 0 deletions modules/core/app/com/elogiclab/guardbee/core/GuardbeeService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ class GuardbeeServicePlugin(app: Application) extends Plugin with GuardbeeServic
(p.asInstanceOf[Authenticator].ProviderId, p.asInstanceOf[Authenticator])
}.toMap
}

def UsernamePasswordAuthenticators: Map[String, UsernamePasswordAuthenticator] = {
Authenticators.filter { a =>
classOf[UsernamePasswordAuthenticator].isAssignableFrom(a._2.getClass)
}.map { a =>
(a._1, a._2.asInstanceOf[UsernamePasswordAuthenticator])
}
}



def UserService[T <: User] = app.plugin[UserService[T]].getOrElse(sys.error("Could not load UserService plugin"))

Expand Down Expand Up @@ -106,6 +116,8 @@ object GuardbeeService extends GuardbeeService {

def Authenticators: Map[String, Authenticator] = plugin.Authenticators

def UsernamePasswordAuthenticators: Map[String, UsernamePasswordAuthenticator] = plugin.UsernamePasswordAuthenticators

def PasswordProvider = plugin.PasswordProvider

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2014 Marco Sarti <marco.sarti at gmail.com>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.elogiclab.guardbee.core

import play.api.mvc.Controller

/**
* @author Marco Sarti
*
*/
object RegistrationController extends Controller {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2014 Marco Sarti <marco.sarti at gmail.com>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.elogiclab.guardbee.core

import play.api.Application
import play.api.Plugin
import org.joda.time.DateTime

/**
* @author Marco Sarti
*
*/

trait RegistrationToken {
self =>


def email: String
def token: String
def expirationTime: DateTime


def isExpired = DateTime.now.isAfter(self.expirationTime)


}

class RegistrationServiceConfig(app: Application) extends Configuration(app) {

}





abstract class RegistrationService(app: Application) extends RegistrationServiceConfig(app) with Plugin {


def findTokenByEmail(email: String): Option[RegistrationToken]
def consumeToken(token: String): Option[RegistrationToken]
def saveToken(token: RegistrationToken): RegistrationToken







}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import play.api.Application
import play.api.mvc.Flash
import play.api.templates.Html
import play.api.data.Form
import play.api.i18n.Lang


/**
Expand All @@ -38,11 +39,11 @@ import play.api.data.Form
*/
trait TemplateManager {

def loginPage(form: Form[UsernamePasswordAuthenticationToken], redirectUrl: String = "/")(implicit flash: Flash): Html
def loginPage(form: Form[UsernamePasswordAuthenticationToken], redirectUrl: String = "/")(implicit flash: Flash, lang: Lang): Html

}

class DefaultTemplateManagerPlugin(app:Application) extends Plugin with TemplateManager {
def loginPage(form: Form[UsernamePasswordAuthenticationToken], redirectUrl: String = "/")(implicit flash: Flash): Html = com.elogiclab.guardbee.core.views.html.login(form, redirectUrl)(flash)
def loginPage(form: Form[UsernamePasswordAuthenticationToken], redirectUrl: String = "/")(implicit flash: Flash, lang: Lang): Html = com.elogiclab.guardbee.core.views.html.login(form, redirectUrl)(flash, lang)
}

105 changes: 46 additions & 59 deletions modules/core/app/com/elogiclab/guardbee/core/views/login.scala.html
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
@* login Template File *@
@(form: Form[com.elogiclab.guardbee.core.UsernamePasswordAuthenticationToken], dest: String)(implicit flash: Flash)
@(form: Form[com.elogiclab.guardbee.core.UsernamePasswordAuthenticationToken], dest: String)(implicit flash: Flash, lang: Lang)
@import com.elogiclab.guardbee.core.RoutesHelper
@import com.elogiclab.guardbee.core.GuardbeeService._
@import views.html.helper
@import com.elogiclab.guardbee.core.views.html.helper.form._
@base("Login") {
<style type="text/css">
.voffset { margin-top: 200px; }
.social-button { margin-top: 5px; }
.btn-facebook { background-color: #3b5998; color: white; }
.btn-google { background-color: #C63D2D; color: white; }
.btn-twitter { background-color: #4099FF; color: white; }
.btn-linkedin { background-color: #4875B4; color: white; }
</style>
<script>
$(function() {
$('#google-login').click(function() {
var url = '@RoutesHelper.loginWith("google", dest)';
$('form').attr('action', url).submit();
});
$('#facebook-login').click(function() {
var url = '@RoutesHelper.loginWith("google", dest)';
$('form').attr('action', url).submit();
});
<style type="text/css">
.voffset { margin-top: 200px; }
.nav-tabs { margin-bottom: 10px; }
.social-button { margin-top: 5px; }
.btn-facebook { background-color: #3b5998; color: white; }
.btn-google { background-color: #C63D2D; color: white; }
.btn-twitter { background-color: #4099FF; color: white; }
.btn-linkedin { background-color: #4875B4; color: white; }
</style>
<script type="text/javascript">
function activateLoginForm(login_type) {
var form_id = login_type+'-login-form';
var tab_id = login_type+'-tab';
$('.form-tab').each( function() {
$(this).removeClass('active');
});
$('#'+tab_id).addClass('active');
$('.login-form').each( function() {
$(this).addClass('hidden');
});
$('#'+form_id).removeClass('hidden');
}

});


</script>
$( function() {
activateLoginForm('local');


$('.form-tab-anchor').click( function(obj) {
var theId = $(obj.target).attr('id');
var str = theId.substring(0, theId.indexOf('-'));
activateLoginForm(str);
});
});
</script>

<div class="container">
@flash.get("error").map { error =>
Expand All @@ -38,45 +51,19 @@
}
<div class="row voffset">
<div class="col-md-4 col-md-offset-4">
<ul class="nav nav-tabs">
@UsernamePasswordAuthenticators.map { a =>
<li class="form-tab" id="@a._1-tab"><a class="form-tab-anchor" id="@a._1-tab-anchor" href="#" name="@a._1-tab-anchor">@Messages("guardbee.label."+a._1+"-login")</a></li>
}
</ul>



<div class="well">
<form role="form" action='@RoutesHelper.login("local", Some(dest))' method="post">
@helper.inputText(form("username"), 'id -> "username", 'class -> "form-control")

@helper.inputPassword(form("password"), 'id -> "password", 'class -> "form-control")

<div class="form-group">

<button type="submit" class="btn btn-primary btn-block">Login</button>

</div>

<div class="row">
<div class="col-xs-6 col-md-8">
<div class="checkbox">
<label>
<input checked="checked" type="checkbox" value="true" name="remember-me"> Remember me
</label>
</div>
</div>


<div class="col-xs-6 col-md-4">
<button type="button" class="btn btn-link pull-right small">Help</button>
</div>
</div>
<div class="row">
<a class="btn btn-facebook col-md-4 col-md-offset-1 social-button" id="facebook-login" href="#">
<i class="fa fa-facebook fa-lg"></i> | Facebook</a>
<a class="btn btn-google col-md-4 col-md-offset-1 social-button" id="google-login" href="#">
<i class="fa fa-google-plus fa-lg"></i> | Google</a>
<a class="btn btn-twitter col-md-4 col-md-offset-1 social-button" href="#">
<i class="fa fa-twitter fa-lg"></i> | Twitter</a>
<a class="btn btn-linkedin col-md-4 col-md-offset-1 social-button" href="#">
<i class="fa fa-linkedin fa-lg"></i> | LinkedIn</a>
</div>

</form>
</div>
@UsernamePasswordAuthenticators.map { a =>
@login_form(a._1, dest)
}
</div>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@* login_form Template File *@
@(authenticator: String, dest: String)(implicit lang: Lang)
@import com.elogiclab.guardbee.core.RoutesHelper
<form role="form" class="hidden login-form" id="@authenticator-login-form" name="@authenticator-login-form" action='@RoutesHelper.login(authenticator, Some(dest))' method="post">
<div class="form-group">
<label class="control-label" for="@authenticator-username">@Messages("guardbee.label.username")</label> <input name="username" class="form-control" id="@authenticator-username" placeholder="Username" type="text">
</div>

<div class="form-group">
<label for="@authenticator-password" class="control-label">@Messages("guardbee.label.password")</label> <input name="password" class="form-control" id="@authenticator-password" placeholder="******" type="password">
</div>

<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">@Messages("guardbee.label.login-with-"+authenticator)</button>
</div>

<div class="row">
<div class="col-xs-6 col-md-8">
<div class="checkbox">
<label><input checked="checked" type="checkbox" value="true" name="remember-me" id="@authenticator-rememeber-me"> @Messages("guardbee.label.remember-me")</label>
</div>
</div>
</div>
</form>
47 changes: 43 additions & 4 deletions modules/core/build.sbt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
play.Project.playScalaSettings

organization := "com.elogiclab"

name := "guardbee-core"

version := "1.0-SNAPSHOT"
organization := Common.buildOrganization

scalaVersion := "2.10.3"
version := Common.buildVersion

scalaVersion := Common.buildScalaVersion

scalacOptions ++= Seq("-Xlint","-deprecation", "-unchecked","-encoding", "utf8")

Expand All @@ -21,11 +22,49 @@ libraryDependencies ++= Seq(
"org.webjars" % "jquery" % "1.11.0",
"org.webjars" % "font-awesome" % "4.0.3",
"commons-codec" % "commons-codec" % "1.8",
"org.mindrot" % "jbcrypt" % "0.3m"
"org.mindrot" % "jbcrypt" % "0.3m",
"com.typesafe" %% "play-plugins-mailer" % "2.2.0"
)

templatesImport += "com.elogiclab.guardbee.core.GuardbeeService._"

publishTo <<= version { v: String =>
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

publishMavenStyle := true

publishArtifact in Test := false

pomIncludeRepository := { x => false }

pomExtra := (
<url>http://www.elogiclab.com</url>
<licenses>
<license>
<name>MIT</name>
<url>http://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git@github.com:elogiclab/guardbee.git</url>
<connection>scm:git:git@github.com:elogiclab/guardbee.git</connection>
</scm>
<developers>
<developer>
<id>msarti</id>
<name>Marco Sarti</name>
<url>http://www.elogiclab.com</url>
</developer>
</developers>
)





Expand Down
9 changes: 9 additions & 0 deletions modules/core/conf/messages
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,13 @@ guardbee.error.internal=Internal error (code: {0})

guardbee.error.authenticationFailed=Invalid username or password

guardbee.label.local-login=Login
guardbee.label.ldap-login=LDAP Login
guardbee.label.login-with-local=Login
guardbee.label.login-with-ldap=Login with LDAP
guardbee.label.remember-me=Remember me
guardbee.label.username=Username
guardbee.label.password=Password



0 comments on commit f7421ed

Please sign in to comment.