Deadbolt 2 in 10 minutes – Scala edition

Deadbolt 2 is an authorization library for Play 2, and features APIs for both Java- and Scala-based applications. It allows you to apply constraints to controller actions, and to customize template rendering based on the current user.

Here’s a short, fast guide to getting started with the Scala version.

Dependencies

Add the dependency to your build

"be.objectify" %% "deadbolt-scala" % "2.4.2"

Add the Deadbolt module to your Play application

play {
    modules {
        enabled += be.objectify.deadbolt.scala.DeadboltModule
    }
}

If you’re already running your app in activator, don’t forgot to reload the project.

Domain model

Implement the Subject, Role and Permission traits.

  • Subject represents, typically, a user
  • A Role is a single system privilege, e.g. **admin**, **user** and so on. A subject can have zero or more roles.
  • A Permission is a can be used with regular expression matching, e.g. a subject with a permission of `printers.admin` can access a resource constrained to `printers.*`, `*.admin`, etc. A subject can have zero or more permissions.

Hooks

Implement the be.objectify.deadbolt.scala.DeadboltHandler trait. This implementation (or implementations – you can more than one) is used to

  • get the current user – getSubject
  • run a pre-authorization task that can block further execution – beforeAuthCheck
  • handle authorization failure – onAuthFailure
  • provide a hook into the dynamic constraint types – getDynamicResourceHandler

You only need to implement be.objectify.deadbolt.scala.DynamicResourceHandler if you’re planning to use Dynamic or Pattern.CUSTOM constraints. Dynamic constraints are tests implemented entirely by your code. This trait has two functions:

  • isAllowed is used by the Dynamic constraint
  • checkPermission is used by the Pattern constraint when the pattern type is CUSTOM

Implement the be.objectify.deadbolt.scala.HandlerCache trait. This is used by Deadbolt to obtain instances of DeadboltHandler‘s, and has two concepts

  1. A default handler. You can always use a specific handler in a template or controller, but if nothing is specified a well-known instance will be used.
  2. Named handlers.

An example implementation follows, based on the sample app.

@Singleton
class MyHandlerCache extends HandlerCache {
    val defaultHandler: DeadboltHandler = new MyDeadboltHandler

    // HandlerKeys is an user-defined object, containing instances of a case class that extends HandlerKey  
    val handlers: Map[Any, DeadboltHandler] = Map(HandlerKeys.defaultHandler -> defaultHandler,
                                                  HandlerKeys.altHandler -> new MyDeadboltHandler(Some(MyAlternativeDynamicResourceHandler)),
                                                  HandlerKeys.userlessHandler -> new MyUserlessDeadboltHandler)

    // Get the default handler.
    override def apply(): DeadboltHandler = defaultHandler

    // Get a named handler
    override def apply(handlerKey: HandlerKey): DeadboltHandler = handlers(handlerKey)
}

Finally, expose your handlers to Deadbolt. To do this, you will need to create a small module that binds your handler cache by type…

package com.example.modules

import be.objectify.deadbolt.scala.cache.HandlerCache
import play.api.inject.{Binding, Module}
import play.api.{Configuration, Environment}
import com.example.security.MyHandlerCache

class CustomDeadboltHook extends Module {
    override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
        bind[HandlerCache].to[MyHandlerCache]
    )
}

…and add it to your application.conf

play {
    modules {
        enabled += be.objectify.deadbolt.scala.DeadboltModule
        enabled += com.example.modules.CustomDeadboltHook
    }
}

Using compile-time dependency injection

If you prefer to wire everything together with compile-time dependency, you don’t need to create a custom module or add DeadboltModule to play.modules.

Instead, dependencies are handled using a custom ApplicationLoader. To make things easier, various Deadbolt components are made available via the be.objectify.deadbolt.scala.DeadboltComponents trait. You will still need to provide a couple of things, such as your HandlerCache implementation, and you’ll then have access to all the usual pieces of Deadbolt.

Here’s an example ApplicationLoader for compile-time DI.

class CompileTimeDiApplicationLoader extends ApplicationLoader  {
  override def load(context: Context): Application 
             = new ApplicationComponents(context).application
}

class ApplicationComponents(context: Context) 
                            extends BuiltInComponentsFromContext(context) 
                            with DeadboltComponents
                            with EhCacheComponents {

  // Define a pattern cache implementation
  // defaultCacheApi is a component from EhCacheComponents
  override lazy val patternCache: PatternCache = new DefaultPatternCache(defaultCacheApi)

  // Declare something required by MyHandlerCache
  lazy val subjectDao: SubjectDao = new TestSubjectDao

  // Specify the DeadboltHandler implementation to use
  override lazy val handlers: HandlerCache = new MyHandlerCache(subjectDao) 

  // everything from here down is application-level
  // configuration, unrelated to Deadbolt, such as controllers, routers, etc
  // ...
}

The components provided by Deadbolt are

  • scalaAnalyzer – constraint logic
  • deadboltActions – for composing actions
  • actionBuilders – for building actions
  • viewSupport – for template constraints
  • patternCache – for caching regular expressions. You need to define this yourself in the application loader, but as in the example above it’s easy to use the default implementation
  • handlers – the implementation of HandlerCache that you provide
  • configuration – the application configuration
  • ecContextProvider – the execution context for concurrent operations. Defaults to scala.concurrent.ExecutionContext.global
  • templateFailureListenerProvider – for listening to Deadbolt-related errors that occur when rendering templates. Defaults to a no-operation implementation

Once you’ve defined your ApplicationLoader, you need to add it to your application.conf.

play {
  application {
    loader=com.example.myapp.CompileTimeDiApplicationLoader
  }
}

Whichever injection approach you take, you’re now ready to secure access to controller functions and templates in your Play 2 application.

Controller constraints with the action builder

Using the ActionsBuilders class, you can quickly assemble constraints around your functions. To get started, inject ActionBuilders into your controller.

class ExampleController @Inject() (actionBuilder: ActionBuilders) extends Controller

You now have builders for all the constraint types, which we’ll take a quick look at in a minute. In the following examples I’m using the default handler, i.e. .defaultHandler() but it’s also possible to use a different handler with .key(HandlerKey) or pass in a handler directly using .withHandler(DeadboltHandler).

SubjectPresent and SubjectNotPresent

Sometimes, you don’t need fine-grained checks – you just need to see if there is a user present (or not present).

// DeadboltHandler#getSubject must result in a Some for access to be granted
def someFunctionA = actionBuilder.SubjectPresentAction().defaultHandler() { Ok(accessOk()) }

// DeadboltHandler#getSubject must result in a None for access to be granted
def someFunctionB = actionBuilder.SubjectNotPresentAction().defaultHandler() { Ok(accessOk()) }

Restrict

This uses the Subject‘s Roles to perform AND/OR/NOT checks. The values given to the builder must match the Role.name of the subject’s roles.

AND is defined as an Array[String] (or more correctly, String*, OR is a List[Array[String]], and NOT is a rolename with a ! preceding it.

// subject must have the "foo" role 
def restrictedFunctionA = actionBuilder.RestrictAction("foo").defaultHandler() { Ok(accessOk()) }

// subject must have the "foo" AND "bar" roles 
def restrictedFunctionB = actionBuilder.RestrictAction("foo", "bar").defaultHandler() { Ok(accessOk()) }

// subject must have the "foo" OR "bar" roles 
def restrictedFunctionC = actionBuilder.RestrictAction(List(Array("foo"), Array("bar"))).defaultHandler() { Ok(accessOk()) }

Pattern

This uses the Subject‘s Permissions to perform a variety of checks.

// subject must have a permission with the exact value "admin.printer" 
def permittedFunctionA = actionBuilders.PatternAction("admin.printer", PatternType.EQUALITY).defaultHandler() { Ok(accessOk()) }

// subject must have a permission that matches the regular expression (without quotes) "(.)*\.printer" 
def permittedFunctionB = actionBuilders.PatternAction("(.)*\.printer", PatternType.REGEX).defaultHandler() { Ok(accessOk()) }

// the checkPermssion function of the current handler's DynamicResourceHandler will be used.  This is a user-defined test 
def permittedFunctionC = actionBuilders.PatternAction("something arbitrary", PatternType.CUSTOM).defaultHandler() { Ok(accessOk()) }

Dynamic

The most flexible constraint – this is a completely user-defined constraint that uses DynamicResourceHandler#isAllowed to determine access.

    def foo = actionBuilder.DynamicAction(name = "someClassifier").defaultHandler() { Ok(accessOk()) }

Controller constraints with action composition

Using the DeadboltActions class, you can compose constrained functions. To get started, inject DeadboltActions into your controller.

    class ExampleController @Inject() (deadbolt: DeadboltActions) extends Controller

You now have functions equivalent to those of the builders mentioned above. In the following examples I’m using the default handler, i.e. no handler is specified, but it’s also possible to use a different handler with handler = <some handler, possibly from the handler cache>.

SubjectPresent and SubjectNotPresent

// DeadboltHandler#getSubject must result in a Some for access to be granted
def someFunctionA = deadbolt.SubjectPresent() {
    Action {
        Ok(accessOk())
    }
}

// DeadboltHandler#getSubject must result in a None for access to be granted
def someFunctionB = deadbolt.SubjectNotPresent() {
    Action {
        Ok(accessOk())
    }
}

Restrict

// subject must have the "foo" role 
def restrictedFunctionA = deadbolt.Restrict(List(Array("foo")) {
    Action {
        Ok(accessOk())
    }
}

// subject must have the "foo" AND "bar" roles 
def restrictedFunctionB = deadbolt.Restrict(List(Array("foo", "bar")) {
    Action {
        Ok(accessOk())
    }
}

// subject must have the "foo" OR "bar" roles 
def restrictedFunctionC = deadbolt.Restrict(List(Array("foo"), Array("bar"))) {
    Action {
        Ok(accessOk())
    }
}

Pattern

// subject must have a permission with the exact value "admin.printer" 
def permittedFunctionA = deadbolt.Pattern("admin.printer", PatternType.EQUALITY) {
    Action {
        Ok(accessOk())
    }
}

// subject must have a permission that matches the regular expression (without quotes) "(.)*\.printer" 
def permittedFunctionB = deadbolt.Pattern("(.)*\.printer", PatternType.REGEX) {
    Action {
        Ok(accessOk())
    }
}

// the checkPermssion function of the current handler's DynamicResourceHandler will be used.  This is a user-defined test in DynamicResourceHandler#checkPermission 
def permittedFunctionC = deadbolt.Pattern("something arbitrary", PatternType.CUSTOM) {
    Action {
        Ok(accessOk())
    }
}

Dynamic

The most flexible constraint – this is a completely user-defined constraint that uses DynamicResourceHandler#isAllowed to determine access.

def foo = deadbolt.Dynamic(name = "someClassifier") {
    Action {
        Ok(accessOk())
    }
}

Template constraints

Using template constraints, you can exclude portions of templates from being generated on the server-side. This is not a client-side DOM manipulation! Template constraints have the same possibilities as controller constraints.

By default, template constraints use the default Deadbolt handler but as with controller constraints you can pass in a specific handler. The cleanest way to do this is to pass the handler into the template and then pass it into the constraints. Another advantage of this approach is you can pass in a wrapped version of the handler that will cache the subject; if you have a lot of constraints in a template, this can yield a significant gain.

One important thing to note here is that templates are blocking, so any Futures used need to be completed for the resuly to be used in the template constraints. As a result, each constraint can take a function that expresses a Long, which is the millisecond value of the timeout. It defaults to 1000 milliseconds, but you can change this globally by setting the deadbolt.scala.view-timeout value in your application.conf.

Each constraint has a variant which allows you to define fallback content. This comes in the format `<constraintName>Or`, e.g.

@subjectPresentOr {
    this is protected
} {
    this will be shown if the constraint blocks the other content
}

SubjectPresent

@import be.objectify.deadbolt.scala.views.html.{subjectPresent, subjectPresentOr}

@subjectPresent() {
    This content will be present if handler#getSubject results in a Some 
}

@subjectPresentOr() {
    This content will be present if handler#getSubject results in a Some 
} {
    fallback content
}

SubjectNotPresent

@import be.objectify.deadbolt.scala.views.html.{subjectNotPresent, subjectNotPresentOr}

@subjectNotPresent() {
    This content will be present if handler#getSubject results in a None 
}

@subjectNotPresentOr() {
    This content will be present if handler#getSubject results in a None 
} {
    fallback content
}

Restrict

@import be.objectify.deadbolt.scala.views.html.{restrict, restrictOr}

@restrict(roles = List(Array("foo", "bar"))) {
    Subject requires the foo role for this to be visible
}

@restrict(List(Array("foo", "bar")) {
     Subject requires the foo AND bar roles for this to be visible
}

@restrict(List(Array("foo"), Array("bar"))) {
     Subject requires the foo OR bar role for this to be visible
}

@restrictOr(List(Array("foo", "bar")) {
     Subject requires the foo AND bar roles for this to be visible
} {
    Subject does not have the necessary roles
}

Pattern

The default pattern type is PatternType.EQUALITY.

@import be.objectify.deadbolt.scala.views.html.{pattern, patternOr}

@pattern("admin.printer") {
    Subject must have a permission with the exact value "admin.printer" for this to be visible
}

@pattern("(.)*\.printer", PatternType.REGEX) {
    Subject must have a permission that matches the regular expression (without quotes) "(.)*\.printer" for this to be visible
}

@pattern("something arbitrary", PatternType.CUSTOM) {
    DynamicResourceHandler#checkPermission must result in true for this to be visible
}

@patternOr("admin.printer") {
    Subject must have a permission with the exact value "admin.printer" for this to be visible
} {
    Subject did not have necessary permissions
}

Dynamic

@import be.objectify.deadbolt.scala.views.html.{dynamic, dynamicOr}

@dynamic("someName") {
    DynamicResourceHandler#isAllowed must result in true for this to be visible
}

@dynamicOr("someName") {
    DynamicResourceHandler#isAllowed must result in true for this to be visible
} {
    Custom test failed
}

Execution context

By default, all futures are executed in the `scala.concurrent.ExecutionContext.global` context. If you want to provide a separate execution context, you can plug it into Deadbolt by implementing the `DeadboltExecutionContextProvider` trait.

import be.objectify.deadbolt.scala.DeadboltExecutionContextProvider

class CustomDeadboltExecutionContextProvider extends DeadboltExecutionContextProvider {
    override def get(): ExecutionContext = ???
}

NB: This provider is invoked twice, once in DeadboltActions and once in ViewSupport.

Once you’ve implemented the provider, you need to declare it in your custom module (see introduction above).

class CustomDeadboltHook extends Module {
    override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
        bind[HandlerCache].to[MyHandlerCache],
        bind[DeadboltExecutionContextProvider].to[CustomDeadboltExecutionContextProvider]
    )
}

What next?

If you want to explore Deadbolt further, you might want to take a look at the book I’m currently writing on it. You can find it at https://leanpub.com/deadbolt-2.

large

Deadbolt 2 in 10 minutes – Java edition

Deadbolt 2 is an authorization library for Play 2, and features APIs for both Java- and Scala-based applications. It allows you to apply constraints to controller actions, and to customize template rendering based on the current user.

Here’s a short, fast guide to getting started with the Java version.

Dependencies

Add the dependency to your build.sbt file.

"be.objectify" %% "deadbolt-java" % "2.4.3"

Add the Deadbolt module to your conf/application.conf file.

play {
	modules {
		enabled += be.objectify.deadbolt.java.DeadboltModule
	}
}

If you’re already running your app in activator, don’t forgot to reload the project.

Domain model

Implement the Subject, Role and Permission interfaces.

  • Subject represents, typically, a user.
  • A Role is a single system privilege, e.g. admin, user and so on. A subject can have zero or more roles.
  • A Permission is a can be used with regular expression matching, e.g. a subject with a permission of printers.admin can access a resource constrained to printers.*, *.admin, etc. A subject can have zero or more permissions.

Hooks

Implement the be.objectify.deadbolt.java.DeadboltHandler interface. This implementation (or implementations – you can have more than one) is used to obtain the subject, apply dynamic constraints, execute pre-authorization tasks and define the behaviour when authorization fails.

  • get the current user – getSubject
  • run a pre-authorization task that can block further execution – beforeAuthCheck
  • handle authorization failure – onAuthFailure
  • provide a hook into the dynamic constraint types – getDynamicResourceHandler

You only need to implement be.objectify.deadbolt.java.DynamicResourceHandler if you’re planning to use Dynamic or Pattern.CUSTOM constraints. Dynamic constraints are tests implemented entirely by your code. This interface has two methods:

  • isAllowed is used by the Dynamic constraint
  • checkPermission is used by the Pattern constraint when the pattern type is CUSTOM

Implement the be.objectify.deadbolt.java.HandlerCache interface. This is used by Deadbolt to obtain an instance of DeadboltHandler, and has two concepts

  1. A default handler. You can always use a specific handler in a template or controller, but if nothing is specified a well-known instance will be used.
  2. Named handlers.

An example implementation follows, based on the sample app. You can, of course, define these any way you want to.

@Singleton
public class MyHandlerCache implements HandlerCache
{
    private final DeadboltHandler defaultHandler = new MyDeadboltHandler();
    private final Map<String, DeadboltHandler> handlers = new HashMap<>();

    public MyHandlerCache()
    {
        handlers.put(HandlerKeys.DEFAULT.key, defaultHandler);
        handlers.put(HandlerKeys.ALT.key, new MyAlternativeDeadboltHandler());
        handlers.put(HandlerKeys.BUGGY.key, new BuggyDeadboltHandler());
        handlers.put(HandlerKeys.NO_USER.key, new NoUserDeadboltHandler());
    }

    @Override
    public DeadboltHandler apply(final String key)
    {
        return handlers.get(key);
    }

    @Override
    public DeadboltHandler get()
    {
        return defaultHandler;
    }
}

Finally, expose your handlers to Deadbolt. To do this, you will need to create a small module that binds your handler cache by type.

package com.example.modules

import be.objectify.deadbolt.java.cache.HandlerCache;
import play.api.Configuration;
import play.api.Environment;
import play.api.inject.Binding;
import play.api.inject.Module;
import scala.collection.Seq;
import security.MyHandlerCache;

import javax.inject.Singleton;

public class CustomDeadboltHook extends Module
{
    @Override
    public Seq<Binding<?>> bindings(final Environment environment,
                                    final Configuration configuration)
    {
        return seq(bind(HandlerCache.class).to(MyHandlerCache.class).in(Singleton.class));
    }
}

…and add it to your application.conf

play {
    modules {
        enabled += be.objectify.deadbolt.java.DeadboltModule
        enabled += com.example.modules.CustomDeadboltHook
    }
}

Ready to rock
You’re now ready to secure access to controller functions and templates in your Play 2 application.

Controller constraints with the action builder

Controller constraints are defined through annotations.

SubjectPresent and SubjectNotPresent

Sometimes, you don’t need fine-grained checked – you just need to see if there is a user present (or not present).

@SubjectPresent
public F.Promise someMethodA() {
    // method will execute if the current DeadboltHandler's getSubject returns Some
}

@SubjectNotPresent
public F.Promise someMethodB() {
    // method will execute if the current DeadboltHandler's getSubject returns None
}

Restrict

This uses the Subjects Roles to perform AND/OR/NOT checks. The values given to the builder must match the Role.name of the subject’s roles.

AND is defined as an @Group OR is an array of @Group, and NOT is a rolename with a ! preceding it.

@Restrict(@Group("foo"))
public F.Promise someMethodA() {
    // method will execute of subject has the "foo" role
}

@Restrict(@Group("foo", "bar"))
public F.Promise someMethodB() {
    // method will execute of subject has the "foo" AND "bar" roles
}

@Restrict({@Group("foo"), @Group("bar")})
public F.Promise someMethodC() {
    // method will execute of subject has the "foo"OR "bar" roles
}

Pattern

This uses the Subjects Permissions to perform a variety of checks.

@Pattern("admin.printer")
public F.Promise someMethodA() {
    // subject must have a permission with the exact value "admin.printer"
}

@Pattern(value = "(.)*\.printer", patternType = PatternType.REGEX)
public F.Promise someMethodB() {
    // subject must have a permission that matches the regular expression (without quotes) "(.)*\.printer"
}

@Pattern(value = "something arbitrary", patternType = PatternType.CUSTOM)
public F.Promise someMethodC() {
    // the checkPermssion method of the current handler's DynamicResourceHandler will be used.  This is a user-defined test
}

If you want to invert the result, i.e. deny access if there’s a match, set the invert attribute to true.

@Pattern(value = "admin.printer", invert = true)
public F.Promise someMethodA() {
    // subject with a permission with the exact value "admin.printer" will by denied
}

Dynamic

The most flexible constraint – this is a completely user-defined constraint that uses DynamicResourceHandler#isAllowed to determine access.

@Dynamic(name = "name of the test")
public F.Promise someMethod() {
    // the method will execute if the user-defined test returns true
}

Template constraints

Using template constraints, you can exclude portions of templates from being generated on the server-side. This is not a client-side DOM manipulation! Template constraints have the same possibilities as controller constraints.

By default, template constraints use the default Deadbolt handler but as with controller constraints you can pass in a specific handler. The cleanest way to do this is to pass the handler into the template and then pass it into the constraints. Another advantage of this approach is you can pass in a wrapped version of the handler that will cache the subject; if you have a lot of constraints in a template, this can yield a significant gain.

One important thing to note here is that templates are blocking, so any Futures used need to be completed for the resuly to be used in the template constraints. As a result, each constraint can take a function that expresses a Long, which is the millisecond value of the timeout. It defaults to 1000 milliseconds, but you can change this globally by setting the deadbolt.java.view-timeout value in your application.conf.

Each constraint has a variant which allows you to define fallback content. This comes in the format xOr, e.g.

@subjectPresentOr {
	this is protected
} {
	this will be shown if the constraint blocks the other content
}

SubjectPresent

@import be.objectify.deadbolt.java.views.html.{subjectPresent, subjectPresentOr}

@subjectPresent() {
    This content will be present if handler#getSubject results in a Some 
}

@subjectPresentOr() {
    This content will be present if handler#getSubject results in a Some 
} {
	fallback content
}

SubjectNotPresent

@import be.objectify.deadbolt.java.views.html.{subjectNotPresent, subjectNotPresentOr}

@subjectNotPresent() {
    This content will be present if handler#getSubject results in a None 
}

@subjectNotPresentOr() {
    This content will be present if handler#getSubject results in a None 
} {
	fallback content
}

Restrict

la and as are convenience functions for creating a List[Array] and an Array[String]

@import be.objectify.deadbolt.java.views.html.{restrict, restrictOr}
@import be.objectify.deadbolt.core.utils.TemplateUtils.{la, as}

@restrict(roles = la(as("foo", "bar"))) {
    Subject requires the foo role for this to be visible
}

@restrict(roles = la(as("foo", "bar")) {
     Subject requires the foo AND bar roles for this to be visible
}

@restrict(roles = la(as("foo"), as("bar"))) {
     Subject requires the foo OR bar role for this to be visible
}

@restrictOr(roles = la(as("foo", "bar"))) {
     Subject requires the foo AND bar roles for this to be visible
} {
	Subject does not have the necessary roles
}

Pattern

The default pattern type is PatternType.EQUALITY.

@import be.objectify.deadbolt.java.views.html.{pattern, patternOr}

@pattern(value = "admin.printer") {
    Subject must have a permission with the exact value "admin.printer" for this to be visible
}

@pattern(value = "(.)*\.printer", patternType = PatternType.REGEX) {
	Subject must have a permission that matches the regular expression (without quotes) "(.)*\.printer" for this to be visible
}

@pattern(value = "something arbitrary", patternType = PatternType.CUSTOM) {
	DynamicResourceHandler#checkPermission must result in true for this to be visible
}

@patternOr(value = "admin.printer") {
    Subject must have a permission with the exact value "admin.printer" for this to be visible
} {
	Subject did not have necessary permissions
}

Dynamic

@import be.objectify.deadbolt.java.views.html.{dynamic, dynamicOr}
    
@dynamic(name = "someName") {
    DynamicResourceHandler#isAllowed must result in true for this to be visible
}
    
@dynamicOr(name = "someName") {
    DynamicResourceHandler#isAllowed must result in true for this to be visible
} {
	Custom test failed
}

JPA

If you’re using JPA, there’s a good chance you’re going to run into issues when entity managers are used across different threads. To address this, you can put Deadbolt into blocking mode – this ensures all DB calls made in the Deadbolt layer are made from the same thread; this has performance implications, but it’s unavoidable with JPA.

To switch to blocking mode, set deadbolt.java.blocking to true in your configuration.

The default timeout is 1000 milliseconds – to change this, use deadbolt.java.blocking-timeout in your configuration.

This example configuration puts Deadbolt in blocking mode, with a timeout of 2500 milliseconds:

deadbolt {
    java {
        blocking=true
        blocking-timeout=2500
    }
}

What next?

If you want to explore Deadbolt further, you might want to take a look at the book I’m currently writing on it. You can find it at https://leanpub.com/deadbolt-2.

large

Fail-fast validations using Java 8 streams

I’ve lost count of the number of times I’ve seen code which fail-fast validates the state of something, using an approach like

public class PersonValidator {
  public boolean validate(Person person) {
    boolean valid = person != null;
    if (valid) valid = person.givenName != null;
    if (valid) valid = person.familyName != null;
    if (valid) valid = person.age != null;
    if (valid) valid = person.gender != null;
    // ...and many more
  }
}

It works, but it’s a brute force approach that’s filled with repetition due to the valid check. If your code style enforces braces for if statements (+1 for that), your method is also three times longer and growing every time a new check is added to the validator.

Using Java 8’s new stream API, we can improve this by taking the guard condition of if (valid) and making a generic validator that handles the plumbing for you.

import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;
 
public class GenericValidator<T> implements Predicate {
 
  private final List<Predicate<T>> validators = new LinkedList<>();
 
  public GenericValidator(List<Predicate<T>> validators) {
    this.validators.addAll(validators);
  }

  @Override
  public boolean test(final T toValidate) {
    return validators.parallelStream()
                     .allMatch(predicate -> predicate.test(toValidate));
  }
} 

Using this, we can rewrite the Person validator to be a specification of the required validations (or even just create a static field of type GenericValidator).

public class PersonValidator extends GenericValidator<Person> {

  private static final List<Predicate<Person>> VALIDATORS = new LinkedList<>();

  static {
    VALIDATORS.add(person -> person.givenName != null);
    VALIDATORS.add(person -> person.familyName != null);
    VALIDATORS.add(person -> person.age != null);
    VALIDATORS.add(person -> person.gender != null);
    // ...and many more
  }

  public PersonValidator() {
    super(VALIDATORS);
  }
}

PersonValidator, and all your other validators, can now focus completely on validation. The behaviour hasn’t changed – the validation still fails fast. There’s no boiler plate, which is A Good Thing.

This one’s going in the toolbox.

UPDATE I saw a comment about this at when it was republished at JCG, and has been re-implemented with the suggestions there. There’s always something new to learn!

“Are recruiters generally all so bad?”

I have a friend who’s a recruiter. Yes, that can actually happen. I mentioned to him that I’d been contacted by a really annoying recruiter, and he responded with “Can I ask you a serious question? Are ‘they’ generally all so bad? I’m struggling a little to understand why there is so much bad feeling generally, towards them.”.

I had a think about this, and here’s the reply I sent him. It’s far from exhaustive, but I think it serves to start a discussion.

Lies

  • Every email or phonecall contains the phrase “this company is the leader in its field”. Generally…no, it’s not.
  • “This is a fantastic opportunity for you”. This may occasionally be true, but when you see it in every email, it’s hard to shake the suspicion that it’s a template.
  • “We pay a referral fee”. I once suggested someone to a recruiter, and the person got the job. Six months later, I repeatedly contacted the recruiter but didn’t get any response so I asked the company HR person to contact them. They finally got back in touch and said the person was actually suggested by someone else, who they named…and I knew that person. I got in touch with him and told him to collect the bounty, but they refused to pay it.
  • If my LinkedIn profile says I’m not interested in a new position, don’t contact me about one and then say “I got your details from a friend of yours”.

Laziness

  • Don’t send me an email that’s completely different to my profile. If you’re contacting me, you either have my CV or you’ve seen my LinkedIn profile.
  • Don’t end every email with “Please pass this onto all your friends”. I don’t ask you to write code, don’t ask me to do your job for free (also see Lies#3).
  • Don’t ask for my CV in Word format; it’s obvious you’re going to cut and paste it into some shitty template so the recruiter’s client won’t see my direct contact details. I put effort into designing my CV, and I don’t want you to destroy it.
  • If you want to connect with me on LinkedIn, don’t use the default message. I am not click-bait.

Personality

  • As a recruiter, I assume you’re a shark-like parasite. If you want to work with me (by which I mean, cream a shitload of money off me), put some effort into building a relationship.

Capabilities

  • If you don’t know anything about technology, don’t pretend you do. “My client is looking for someone with experience X, which I see you have” is fine; “…yeah, it’s really cutting edge stuff like [some dead technology]…” is bullshit.
  • Don’t make promises you can ‘t keep.

Market

  • It’s a seller’s market. As an developer, I’m selling something. As a recruiter, you’re forcing yourself into the market as a broker. Brokers are plentiful; good developers are not. Convince me why I should use you to broker my skills; preferably, don’t use bullshit during this process.

Finally, two thoughts

  • If I say I’m not interested in a role, it means I’m not interested in a role. Wheedling, begging and threatening (happened to a friend of mine!) will not change anything, except I’ve now blacklisted your name and your company.
  • Developers talk. If you’re an asshole, that piece of news will spread.

Testing your plugin with multiple version of Play

So, you’ve written a plugin for Play…are you sure it works?

I’ve been giving Deadbolt some love recently, and as part of the work I’ve added a test application for functional testing. This is an application that uses all the features of Deadbolt, and is driven by HTTP calls by REST-Assured. Initially, it was based on Play 2.3.5 but this ignores the supported Play versions of 2.3.1 through to 2.3.4. Additionally, those hard-working people on the Play team at Typesafe keep cranking out new feature-filled versions.

On top of that, support for Scala 2.10.4 and 2.11.1 is required so cross-Scala version testing is needed.

Clearly, testing your plugin against a single version of Play is not enough. Seems like some kind of continuous integration could help us out here…

Building on Travis CI

Deadbolt builds on Travis CI, a great CI platform that’s free for open-source projects. This runs the tests, and publishs snapshot versions to Sonatype. I’m not going into detail on this, because there’s already a great guide over at Cake Solutions. You can find the guide here: http://www.cakesolutions.net/teamblogs/publishing-artefacts-to-oss-sonatype-nexus-using-sbt-and-travis-ci-here…

I’ve made some changes to the build script because the plugin code is not at the top level of the repositry; rather, it resides one level down. The repository looks like this:

deadbolt-2-java
  |-code        # plugin code lives here
  |-test-app    # the functional test application

As a result, the .travis.yml file that defines the build, looks like this.

language: scala
jdk:
- openjdk6
scala:
- 2.11.1
script:
- cd code
- sbt ++$TRAVIS_SCALA_VERSION +test
- cd ../test-app
- sbt ++$TRAVIS_SCALA_VERSION +test
- cd ../code
- sbt ++$TRAVIS_SCALA_VERSION +publish-local
after_success:
- ! '[[ $TRAVIS_BRANCH == "master" ]] && { sbt +publish; };'
env:
global:
- secure: foo
- secure: bar

This sets the Java version (people get angry when I don’t provide Java 6-compatible versions), and defines a script as the build process. Note the cd commands used to switch between the plugin directory and the test-app directory.

This script already covers the cross-Scala version requirement – prefixing a command with +, e.g. +test, will execute that command against all versions of Scala defined in your build.sbt. It’s important to note that although only Scala 2.11.1 is defined in .travis.yml, SBT itself will take care of setting the current build version based on build.sbt.

crossScalaVersions := Seq("2.11.1", "2.10.4")

Testing multiple versions of Play

However, the version of Play used by the test-app is still hard-coded to 2.3.5 in test-app/project/plugins.sbt.

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.5")

Happily, .sbt files are not just configuration files but actual code. This means we can change the Play version based on environment properties. A default value of 2.3.5 is given to allow the tests to run locally without having to set the version.

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % System.getProperty("playTestVersion", "2.3.5"))

Finally, we update .travis.yml to take advantage of this.

language: scala
jdk:
- openjdk6
scala:
- 2.11.1
script:
- cd code
- sbt ++$TRAVIS_SCALA_VERSION +test
- cd ../test-app
- sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.1 +test
- sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.2 +test
- sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.3 +test
- sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.4 +test
- sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.5 +test
- cd ../code
- sbt ++$TRAVIS_SCALA_VERSION +publish-local
after_success:
- ! '[[ $TRAVIS_BRANCH == "master" ]] && { sbt +publish; };'
env:
global:
- secure: foo
- secure: bar

This means the following steps occur during the build:

  • sbt ++$TRAVIS_SCALA_VERSION +test
    • Run the plugin tests against Scala 2.11.1
    • Run the plugin tests against Scala 2.10.4
  • sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.1 +test
    • Run the functional tests of the test-app against Scala 2.11.1 and Play 2.3.1
    • Run the functional tests of the test-app against Scala 2.10.4 and Play 2.3.1
  • sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.2 +test
    • Run the functional tests of the test-app against Scala 2.11.1 and Play 2.3.2
    • Run the functional tests of the test-app against Scala 2.10.4 and Play 2.3.2
  • sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.3 +test
    • Run the functional tests of the test-app against Scala 2.11.1 and Play 2.3.3
    • Run the functional tests of the test-app against Scala 2.10.4 and Play 2.3.3
  • sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.4 +test
    • Run the functional tests of the test-app against Scala 2.11.1 and Play 2.3.4
    • Run the functional tests of the test-app against Scala 2.10.4 and Play 2.3.4
  • sbt ++$TRAVIS_SCALA_VERSION -DplayTestVersion=2.3.5 +test
    • Run the functional tests of the test-app against Scala 2.11.1 and Play 2.3.5
    • Run the functional tests of the test-app against Scala 2.10.4 and Play 2.3.5

If all these steps pass, the after_success branch of the build script will execute. If any of the steps fail, the build will break and the snapshots won’t be published.

You can take a look at a repository using this approach here: https://github.com/schaloner/deadbolt-2-java.

The resulting Travis build is available here: https://travis-ci.org/schaloner/deadbolt-2-java.

Deadbolt 2.3.2 released

After a fruitful weekend of coding (and DIY, but that’s not relevant to this), Deadbolt 2.3.2 has been released. The major change is that it’s available via Maven Central, so there’s no need to add a resolver for it.

This line can be removed from your build.sbt – don’t let the door hit its ass on the way out:

resolvers += Resolver.url("Objectify Play Repository", url("http://deadbolt.ws/releases/"))(Resolver.ivyStylePatterns)

NB Older versions of Deadbolt are not yet in Maven, so you’ll still need the resolver for versions < 2.3.2. I’ll be publishing them to Maven as and when time allows.

I used the following guides to prepare all three Deadbolt libraries (deadbolt-core, -java and -scala) to Sonatype:
Deploying to Sonatype :: http://www.scala-sbt.org/0.13/docs/Using-Sonatype.html
Publishing Scala libraries to Sonatype :: http://www.loftinspace.com.au/blog/publishing-scala-libraries-to-sonatype.html

DeadboltHandler#getSubject
The other change relates to DeadboltHandler#getSubject. Until now, this has been a synchronous call that returns the Subject itself. As of 2.3.2, it now returns something a bit nicer for a reactive architecture.

Scala
The signature of the DeadboltHandler trait has changed from def getSubject[A](request: Request[A]): Option[Subject] and is now def getSubject[A](request: Request[A]): Future[Option[Subject]]. It’s a simple procedure to update your code. In place of

override def getSubject[A](request: Request[A]): Option[Subject] = {
    Some(however you retrieve your user)
}

you can replace it with

override def getSubject[A](request: Request[A]): Future[Option[Subject]] = {
    Future(Some(however you retrieve your user))
}

Java
The signature of the DeadboltHandler interface has changed from Subject getSubject(Http.Context context) and is now F.Promise getSubject(Http.Context context).

Existing code which looks something like

public Subject getSubject(Http.Context context) {
    return AuthorisedUser.findByUserName("steve");
}

would now look like

public F.Promise getSubject(Http.Context context) {
    return F.Promise.promise(new F.Function0() {
        @Override
        public Subject apply() throws Throwable {
            return AuthorisedUser.findByUserName("steve");
        }
    });
}

All the code is available in GitHub.

If you have any questions or issues, please let me know.

Keep Playing!

JavaScript routing in Play 2 (Scala edition)

In my previous post, I covered using JavaScript routing in Play 2 Java applications. Here’s the Scala version. It’s pretty much a copy of the previous article, to make it independent.

One of the nicest features in Play 2, but one which doesn’t seem to be widely covered, is the
JavaScript routing that can be generated by the framework to make AJAX-based client code more maintainable. Here, I’m going to cover using this feature in a Scala-based Play 2 application.

Overview

It’s common to see calls in JavaScript making AJAX requests. Frequently, a library such as jQuery is used to provide support. For example, given a route

GET    /foo    controllers.Application.getAll()

a GET request can be made using the shorthand $.get method.

$.get("/foo", function( data ) {
  // do something with the response
});

A variant, in the case where parameters are required, needs a little bit more work.

GET    /foo    controllers.Application.get(personId: Long, taskId: Long)

var personId = $('#person').val();
var taskId = $('#item').val();
$.get("/foo?person=" + personId + '&task=' + taskId, 
      function( data ) {
        // do something with the response
      });

All this seems far removed from the easy style of Play applications, where interactions are idiomatic and typesafe. Happily, Play offers a feature called JavaScript routing. This allows us to use JS objects generated by the back-end, and so we can replace the code above with

var personId = $('#person').val();
var taskId = $('#item').val();
appRoutes.controllers.Application.get(personId, taskId).ajax({
  success: function( data ) {
    // do something with the response
  }
})

This will result in a GET request to /foo with personId and taskId as request parameters.

GET /foo?personId=personId&taskId=taskId

Changing the route file to use a RESTful-style URL of /foo/:personId/:taskId will result in the following call with no changes required to your JS code:

GET /foo/personId/taskId

Let’s take a look at what we need to do to achieve this.

The basics

Time to create our basic application. Using the command line, generate a new Play app

play new jsRoutingScala

Accept the default name of jsRoutingScala, and select the option for a Scala application.

 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/

play! 2.1.5 (using Java 1.7.0_17 and Scala 2.10.0), http://www.playframework.org

The new application will be created in /tmp/jsRoutingScala

What is the application name? [jsRoutingScala]
> 

Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 1
OK, application jsRoutingScala is created.

Have fun!

This will give us a basic controller called Application, and a couple of views. We still need to create a model class, so let’s do that now. In the app directory, create a package called models. In the models package, create a class called Person. Note the JSON read/write support – this will allow the controller to serialize and deserialize instances of Person between Scala and JSON.

package models

import anorm._
import anorm.SqlParser._
import play.api.Play.current
import play.api.db.DB
import play.api.libs.json._
import anorm.~

case class Person(id: Pk[Long] = NotAssigned, name: String)

object Person {

  val simple = {
    get[Pk[Long]]("person.id") ~
      get[String]("person.name") map {
      case id~name => Person(id, name)
    }
  }

  def insert(person: Person) = {
    DB.withConnection { implicit connection =>
      SQL(
        """
          insert into person values (
            (select next value for person_seq),
            {name}
          )
        """
      ).on(
        'name -> person.name
      ).executeInsert()
    } match {
      case Some(long) => long
      case None       => -1
    }
  }

  def delete(id: Long) = {
    DB.withConnection { implicit connection =>
      SQL("delete from person where id = {id}").on('id -> id).executeUpdate()
    }
  }

  def getAll: Seq[Person] = {
    DB.withConnection { implicit connection =>
      SQL("select * from person").as(Person.simple *)
    }
  }

  implicit object PersonReads extends Reads[Person] {
    def reads(json: JsValue): JsResult[Person] =
      JsSuccess[Person](Person(NotAssigned, (json \ "name").as[String]), JsPath())
  }

  implicit object PersonWrites extends Writes[Person] {
    def writes(person: Person) = Json.obj(
      "id" -> Json.toJson(person.id.get),
      "name" -> Json.toJson(person.name)
    )
  }
}

We’ll need a database, so edit the conf/application.conf and uncomment the following lines:

db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"

Because this example uses Anorm, we need to configure the database ourselves. In the conf folder, create a folder called evolutions that contains another folder, default. Create a file here called 1.sql, and copy the following into it:

# --- !Ups
create table person (
  id bigint not null,
  name varchar(255),
  constraint pk_person primary key (id))
;

create sequence person_seq;

# --- !Downs
SET REFERENTIAL_INTEGRITY FALSE;

drop table if exists person;

SET REFERENTIAL_INTEGRITY TRUE;

drop sequence if exists person_seq;

We’re now ready to build our controller.

The controller

In the controllers package, open the Application object. There’s already an index method, but we don’t need to change this.

The app will allow us to create, delete and get Person instances, and so we need methods to support these operations.

def getAll() = Action {
  Ok(Json.toJson(Person.getAll))
}

def delete(id: Long) = Action {
  Person.delete(id)
  Ok("Deleted " + id)
}

def create = Action { implicit request =>
  request.body.asJson match {
    case None => BadRequest
    case Some(json: JsValue) => {
      val person: Person = json.as[Person]
      val id = Person.insert(person)
      Ok(Json.obj(
        "id" -> id,
        "name" -> person.name
      ))
    }
  }
}

These methods cover our business logic, so we can add them to the routes file

GET     /person       controllers.Application.getAll()
DELETE  /person/:id   controllers.Application.delete(id: Long)
POST    /person       controllers.Application.create()

Add JS routing support

So far, so normal. We have business logic that can be accessed via HTTP calls, but no specialised JS support. We need to add another method to the controller that specifies which routes we want to be available in the JS routing object.

def jsRoutes = Action { implicit request =>
  Ok(Routes.javascriptRouter("appRoutes")(
    controllers.routes.javascript.Application.create,
    controllers.routes.javascript.Application.delete,
    controllers.routes.javascript.Application.getAll))
    .as("text/javascript")
}

This method will generate a JavaScript file that can be loaded into the client. We’ll see this when we get to the view. Because it’s something called from the client, we need to add another entry to the routes. It’s extremely important to note the placement of the route – it must precede the existing “/assets/*file” entry, otherwise that route will consume the request.

GET           /assets/js/routes             controllers.Application.jsRoutes()
GET           /assets/*file                 controllers.Assets.at(path="/public", file)

The view

Now we get to where the action is. The first step is to make our view aware of the JS routing code, and we do this by simply adding a script tag to views/main.scala.html

<script src="@controllers.routes.Application.jsRoutes()" type="text/javascript"></script>

We’re finally ready to use our JS routing object. The following code is an utterly basic single-page app that hooks into the get, create and delete functionality of the back-end. Copy and paste this code into your existing views/index.scala.html file, and then take a look at what it’s doing. You may notice this code is identical to that in the Java example.

@(message: String)

@main("Play 2 JavaScript Routing") {

    <fieldset>
        <form>
            <label for="personName">Name:
            <input type="text" name="personName" id="personName"/>
            <input type="button" value="Create" id="createPerson"/>
        </form>
    </fieldset>
    <ul id="peopleList">

    <script>
    var doc = $ (document);
    doc.ready (function() {
      // Delete a person
      doc.on ('click', '.deletePerson', function(e) {
        var target = $(e.target);
        var id = target.data('id');
        appRoutes.controllers.Application.delete(id).ajax( {
          success : function ( data ) {
            target.closest('li').remove();
          }
        });
      });

      // Create a new person
      $('#createPerson').click(function() {
        var personNameInput = $('#personName');
        var personName = personNameInput.val();
        if(personName && personName.length > 0) {
          var data = {
            'name' : personName
          };
          appRoutes.controllers.Application.create().ajax({
            data : JSON.stringify(data),
            contentType : 'application/json',
            success : function (person) {
              $('#peopleList').append('<li>' + person.name + ' <a href="#" data-id="' + person.id + '" class="deletePerson">Delete</a></li>');
                personNameInput.val('');
            }
          });
        }
      });

      // Load existing data from the server
      appRoutes.controllers.Application.getAll().ajax({
        success : function(data) {
          var peopleList = $('#peopleList');
          $(data).each(function(index, person) {
            peopleList.append('<li>' + person.name + ' <a href="#" data-id="' + person.id + '" class="deletePerson">Delete</a></li>');
          });
        }
      });
    }) ;
    </script>
}

There are three lines here that will generate calls to the server, namely

  • appRoutes.controllers.Application.delete(id).ajax
  • appRoutes.controllers.Application.create().ajax
  • appRoutes.controllers.Application.getAll().ajax

Let’s take delete as the example, since it takes a parameter.

  • appRoutes
    • Take a look at your Application class, and you’ll see the name appRoutes being given to the JS router. This forms the base of the namespace of the JS routing object, and means you can have multiple JS routing objects from different controllers imported into the same view because you can keep the names of each unique.
  • controllers.Application
    • This is the fully qualified name of the target controller. Note that it matches the FQN of the Scala object.
  • delete(id)
    • The method call, including parameters. This function will return an object called ajax which can be used to control the behaviour of the HTTP call.
  • ajax
    • This function makes the call to the server. It’s here that you add success and error callbacks, change the content-type of the request to match your back-end requirements, add PUT or POST data, etc.

Summary

That seemed like a lot of work, but most of it was creating the project. The actual JS routing represents a very small time investment, for a pretty good pay-off. It’s very easy to retrofit existing code to use this approach, and very simple to continue in this style once you experience the benefits.

Example application

You can find the example code from this article on GitHub: https://github.com/schaloner/jsRoutingScala

Java

This article covered how to use this feature from a Scala viewpoint. In a sibling article, Java support is also demonstrated. The differences between the two are minimal, and non-existent from a client-side perspective. You can read this article here.

JavaScript routing in Play 2 (Java edition)

One of the nicest features in Play 2, but one which doesn’t seem to be widely covered, is the
JavaScript routing that can be generated by the framework to make AJAX-based client code more maintainable. Here, I’m going to cover using this feature in a Java-based Play 2 application.

Overview

It’s common to see calls in JavaScript making AJAX requests. Frequently, a library such as jQuery is used to provide support. For example, given a route

GET    /foo    controllers.Application.getAll()

a GET request can be made using the shorthand $.get method.

$.get("/foo", function( data ) {
  // do something with the response
});

A variant, in the case where parameters are required, needs a little bit more work.

GET    /foo    controllers.Application.get(personId: Long, taskId: Long)

var personId = $('#person').val();
var taskId = $('#item').val();
$.get("/foo?person=" + personId + '&task=' + taskId, 
      function( data ) {
        // do something with the response
      });

All this seems far removed from the easy style of Play applications, where interactions are idiomatic and typesafe. Happily, Play offers a feature called JavaScript routing. This allows us to use JS objects generated by the back-end, and so we can replace the code above with

var personId = $('#person').val();
var taskId = $('#item').val();
appRoutes.controllers.Application.get(personId, taskId).ajax({
  success: function( data ) {
    // do something with the response
  }
})

This will result in a GET request to /foo with personId and taskId as request parameters.

GET /foo?personId=personId&taskId=taskId

Changing the route file to use a RESTful-style URL of /foo/:personId/:taskId will result in the following call with no changes required to your JS code:

GET /foo/personId/taskId

Let’s take a look at what we need to do to achieve this.

The basics

Time to create our basic application. Using the command line, generate a new Play app

play new jsRoutingJava

Accept the default name of jsRoutingJava, and select the option for a Java application.

 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/

play! 2.1.5 (using Java 1.7.0_17 and Scala 2.10.0), http://www.playframework.org

The new application will be created in /tmp/jsRoutingJava

What is the application name? [jsRoutingJava]
> 

Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 2
OK, application jsRoutingJava is created.

Have fun!

This will give us a basic controller called Application, and a couple of views. We still need to create a model class, so let’s do that now. In the app directory, create a package called models. In the models package, create a class called Person.

package models;

import play.db.ebean.Model;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.List;

@Entity
public class Person extends Model
{
    private static Finder FIND = new Finder<>(Long.class, Person.class);
															
    @Id
    public Long id;
	
    public String name;
	
    public static List getAll()
    {
        return FIND.all();
    }
	
    public static Person getById(Long id)
    {
        return FIND.byId(id);
    }
}

We’ll need a database, so edit the conf/application.conf and uncomment the following lines:

db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
ebean.default="models.*"

We’re now ready to build our controller.

The controller

In the controllers package, open the Application class. There’s already an index method, but we don’t need to change this.

The app will allow us to create, delete and get Person instances, and so we need methods to support these operations.

public static Result getAll()
{
    return ok(Json.toJson(Person.getAll()));
}

public static Result delete(Long id)
{
    Result result;
    Person person = Person.getById(id);
    if (person == null)
    {
        person.delete();
        result = ok(person.name + " deleted");
    }
    else
    {
        result = notFound(String.format("Person with ID [%d] not found", id));
    }
    return result;
}

public static Result create()
{
    JsonNode json = request().body().asJson();
    Person person = Json.fromJson(json, Person.class);
    person.save();
    return ok(Json.toJson(person));
}

These methods cover our business logic, so we can add them to the routes file

GET     /person       controllers.Application.getAll()
DELETE  /person/:id   controllers.Application.delete(id: Long)
POST    /person       controllers.Application.create()

Add JS routing support

So far, so normal. We have business logic that can be accessed via HTTP calls, but no specialised JS support. We need to add another method to the controller that specifies which routes we want to be available in the JS routing object.

public static Result jsRoutes()
{
    response().setContentType("text/javascript");
    return ok(Routes.javascriptRouter("appRoutes", //appRoutes will be the JS object available in our view
                                      routes.javascript.Application.getAll(),
                                      routes.javascript.Application.delete(),
                                      routes.javascript.Application.create()));
}

This method will generate a JavaScript file that can be loaded into the client. We’ll see this when we get to the view. Because it’s something called from the client, we need to add another entry to the routes. It’s extremely important to note the placement of the route – it must precede the existing “/assets/*file” entry, otherwise that route will consume the request.

GET           /assets/js/routes             controllers.Application.jsRoutes()
GET           /assets/*file                 controllers.Assets.at(path="/public", file)

The view

Now we get to where the action is. The first step is to make our view aware of the JS routing code, and we do this by simply adding a script tag to views/main.scala.html

<script src="@controllers.routes.Application.jsRoutes()" type="text/javascript"></script>

We’re finally ready to use our JS routing object. The following code is an utterly basic single-page app that hooks into the get, create and delete functionality of the back-end. Copy and paste this code into your existing views/index.scala.html file, and then take a look at what it’s doing.

@(message: String)

@main("Play 2 JavaScript Routing") {

    <fieldset>
        <form>
            <label for="personName">Name:
            <input type="text" name="personName" id="personName"/>
            <input type="button" value="Create" id="createPerson"/>
        </form>
    </fieldset>
    <ul id="peopleList">

    <script>
    var doc = $ (document);
    doc.ready (function() {
      // Delete a person
      doc.on ('click', '.deletePerson', function(e) {
        var target = $(e.target);
        var id = target.data('id');
        appRoutes.controllers.Application.delete(id).ajax( {
          success : function ( data ) {
            target.closest('li').remove();
          }
        });
      });

      // Create a new person
      $('#createPerson').click(function() {
        var personNameInput = $('#personName');
        var personName = personNameInput.val();
        if(personName && personName.length > 0) {
          var data = {
            'name' : personName
          };
          appRoutes.controllers.Application.create().ajax({
            data : JSON.stringify(data),
            contentType : 'application/json',
            success : function (person) {
              $('#peopleList').append('<li>' + person.name + ' <a href="#" data-id="' + person.id + '" class="deletePerson">Delete</a></li>');
                personNameInput.val('');
            }
          });
        }
      });

      // Load existing data from the server
      appRoutes.controllers.Application.getAll().ajax({
        success : function(data) {
          var peopleList = $('#peopleList');
          $(data).each(function(index, person) {
            peopleList.append('<li>' + person.name + ' <a href="#" data-id="' + person.id + '" class="deletePerson">Delete</a></li>');
          });
        }
      });
    }) ;
    </script>
}

There are three lines here that will generate calls to the server, namely

  • appRoutes.controllers.Application.delete(id).ajax
  • appRoutes.controllers.Application.create().ajax
  • appRoutes.controllers.Application.getAll().ajax

Let’s take delete as the example, since it takes a parameter.

  • appRoutes
    • Take a look at your Application class, and you’ll see the name appRoutes being given to the JS router. This forms the base of the namespace of the JS routing object, and means you can have multiple JS routing objects from different controllers imported into the same view because you can keep the names of each unique.
  • controllers.Application
    • This is the fully qualified name of the target controller. Note that it matches the FQN of the Java class.
  • delete(id)
    • The method call, including parameters. This function will return an object called ajax which can be used to control the behaviour of the HTTP call.
  • ajax
    • This function makes the call to the server. It’s here that you add success and error callbacks, change the content-type of the request to match your back-end requirements, add PUT or POST data, etc.

Summary

That seemed like a lot of work, but most of it was creating the project. The actual JS routing represents a very small time investment, for a pretty good pay-off. It’s very easy to retrofit existing code to use this approach, and very simple to continue in this style once you experience the benefits.

Happy new year.

Example application

You can find the example code from this article on GitHub: https://github.com/schaloner/jsRoutingJava

Scala

This article covered how to use this feature from a Java viewpoint. In a sibling article, Scala support is also demonstrated. The differences between the two are minimal, and non-existent from a client-side perspective. The Scala article will be available soon is available here.

Banks and social engineering – a short story of fail

The fair is in town, and I need money. Where do I get money from? The bank.

I enter the bank. I see a piece of paper loosely stuck to the ATM advertising the bank’s mobile application, and conveniently including a QR code.

Anyone else see a problem here?

Examples of malicious QR code were already being reported two years ago. Is it really such a stretch of the imagination, given the number of phishing sites that mimic banks, that fraudulent mobile applications won’t appear? QR codes represent a potential path to get these apps onto devices.

For any company to offer an app via a QR code printed on a scrap of paper and pasted to the side of an ATM shows a stunning lack of understanding of the potential for damage. Even an offical poster bearing a QR code can be hijacked by scammers placing QR code stickers over the true QR code. Even that modicum of effort isn’t needed in this situation. A scammer can print out a piece of paper, fasten it to an ATM after the bank has closed, and remove it before the bank opens.

What could the app do?
An app that you cheerfully feed your bank details into can at least harvest your account details. If your bank’s online browser-based web app requires a card reader code to access, that code can be requested by the mobile app and used to – manually or automatically – log into the bank’s web app. A simple “service unavailable” message delivered to the user leads them to believe no access has occurred, while in reality their account is being drained.

An unlikely scenario? Hardly. Nothing I have described above is new, and even fairly rudimentary coding skills would suffice to pull this off.

What should the bank do?
Not use QR codes! If my bank calls me with a question, I tell them I’ll call them back and hang up. I never accept “pushed” data – instead, I get the phone number from my bank documentation and call that number. The same principle applies here – banks should advertise the availability of mobile apps, but actual installation should only occur from a trusted source.

Needless to say, I don’t scan QR codes.

A good, lazy way to write tests

Testing. I’ve been thinking a lot about testing recently. As part of code reviews I’ve done for various projects, I’ve seen thousands of lines of untested code. This is not just a case of test coverage statistics pointing this out, it’s more a case of there not being any tests at all in this projects. And the two reason I keep hearing for this sad state of affairs? “We don’t have time”, swiftly followed by “We’ll do it when we’ve finished the code”.

What I present here is not a panacea for testing. It covers unit testing, and specifically, unit testing of interfaces. Interfaces are good things. Interfaces define contracts. Interfaces, regardless of how many implementations they have, can be tested easily and with very little effort. Let’s see how, using this class structure as an example.

A simple inheritence tree

CustomerService is our interface. It has two methods, to keep the example simple, and is described below. Note the javadoc – this is where the contract is described.

public interface CustomerService
{
    /**
     * Retrieve the customer from somewhere.
     * @param userName the userName of the customer
     * @return a non-null Customer instance compliant with the userName
     * @throws CustomerNotFoundException if a customer with the given user name can not be found
     */
    Customer get(String userName) throws CustomerNotFoundException;

    /**
     * Persist the customer.
     * @param customer the customer to persist
     * @return the customer as it now exists in its persisted form
     * @throws DuplicateCustomerException if a customer with the user name already exists
     */
    Customer create(Customer customer) throws DuplicateCustomerException;
}

As we can see from the diagram, we have two implementations of this class, RemoteCustomerService and CachingCustomerService. The implementations of these are not shown, because they don’t matter. How can I say this? Simple – we are testing the contract. We write tests for every method in the interface, along with every permutation of the contract. For example, for get() we need to test what happens when a customer with the given user name is present, and what happens when it isn’t present.

public abstract class CustomerServiceTest
{
    @Test
    public void testCreate()
    {
        CustomerService customerService = getCustomerService();
        Customer customer = customerService.create(new Customer("userNameA"));

        Assert.assertNotNull(customer);
        Assert.assertEquals("userNameA",
                            customer.getUserName());
    }

    @Test(expected = DuplicateCustomerException.class)
    public void testCreate_duplicate()
    {
        CustomerService customerService = getCustomerService();
        Customer customer = new Customer("userNameA");
        customerService.create(customer);
        customerService.create(customer);
    }

    @Test
    public void testGet()
    {
        CustomerService customerService = getCustomerService();
        customerService.create(new Customer("userNameA"));
        Customer customer = customerService.get("userNameA");
        
        Assert.assertNotNull(customer);
        Assert.assertEquals("userNameA",
                            result.getUserName());
    }

    @Test(expected = CustomerNotFoundException.class)
    public void testGet_noUser()
    {
        CustomerService customerService = getCustomerService();
        customerService.get("userNameA");
    }

    public abstract CustomerService getCustomerService();
}

We now have a test for the contract, and at no point have we mentioned any of the implementations. This means two things:

  • We don’t need to duplicate the tests for each and every implementation. This is a Very Good Thing.
  • None of the implementations are being tested. We can correct this by adding one test class per implementation. Since each test class will be almost identical, I’ll just show the test of RemoteCustomerService.
public class RemoteCustomerServiceTest extends CustomerServiceTest
{
    public CustomerService getCustomerService()
    {
        return new RemoteCustomerService();
    }
}

And that’s it! We now have a very simple way to test multiple implementations of any interface by putting in the hard work up front, and reducing the effort of testing new implementations to a single, simple method.

This post is part of a series as explained in I am not a good teacher.