Secure social login and Play authenticator together

It is quite common use facebook, twitter and other social networks as a login provider for application. In Play world, Secure Social is one of the most used! Here in the blog there is a tutorial that guides you to configure this extension in your project. But, it is also important that your web app provides a formal way to register new users, using a common registration form.

For this last case, the normal way to control user access is using the Play plugin, provided by the framework “out of the box”. The problem here is the integration between these two plugins. When your user authenticates through a social network, Secure Social is the one responsible for checking the access control, it already has annotations for this case. While that when the user authenticates, for instance, through your database, you will probably want to use the plugin annotation provided by Play to control the user access.

In order to use both together, you have to change the Play’s session with information that came from the social login. The good news is that Secure Social has this exactly feature! You can create a listener that can be notified when new social login is done :). Let’s see the code.

    class SocialLoginEventListener(app: play.Application) extends EventListener {
      override def id: String = "my_event_listener"

      def onEvent(event: Event, request: RequestHeader, session: Session): Option[Session] = {
        event match {
          case e: LoginEvent => {
            val loggedUser = event.user.asInstanceOf[WrapIdentity].getUser()
            Some(session.+(("email",loggedUser.getEmail())))
          }

          case e:LogoutEvent => Option(Session.deserialize(Map[String,String]()))
          case _ => None
        }
      }
    }

You just have to change the session. I put the email information here because this is the key being used for my Play Authenticator, fell free to change and use what is better for you. Another point is that Secure Social provides only a Scala version of this feature. Remember, it is not a problem, your Play project is Java and Scala! You can combine both languages to take advantage of both worlds.

Now you have to configure Secure Social to use your listener. You have to add an entry in your play.plugins file.

  9994:securesocial.core.DefaultAuthenticatorStore
  9995:securesocial.core.DefaultIdGenerator
  9997:securesocial.controllers.DefaultTemplatesPlugin
  #my implementation of a service
  9998:security.SocialUserService
  10001:securesocial.core.providers.FacebookProvider
  10009:securesocial.core.providers.InstagramProvider
  #listener
  10006:security.SocialLoginEventListener

That is it, now you are able to use both login ways together without a problem! As last week I did not write,  I am gonna write twice in this one.

Using Play-S3 plugin to upload files to Amazon.

One of the most common task in applications around the world is the file upload. And, nowadays, instead of store these files in our server, is quite normal send them to Amazon S3. In this post let’s see how to use the Play-S3 plugin for a Play application using Java.

The first problem is that this plugin only has a Scala version. What are you gonna do? Are you going to implement everything again? It seems a little bit over… As we has already discussed in another post, your Play project is Java and Scala, together! Let’s mix both languages and take advantage of this plugin.

The first thing you have to do is to add the Play-s3 as a dependency in your build.sbt file.

    libraryDependencies ++= Seq(
      javaJdbc,
      cache,
      javaJpa,
      "org.hibernate" % "hibernate-entitymanager" % "3.6.9.Final",
       "mysql" % "mysql-connector-java" % "5.1.20",
       "org.mindrot" % "jbcrypt" % "0.3m",
       "ws.securesocial" %% "securesocial" % "2.1.3",
       "nl.rhinofly" %% "play-s3" % "3.3.5"
)

Now you have to configure your access and secret key in order to enable the upload of files to S3. This configuration, as usual, is placed in the *.conf file of your application.

  aws.accessKeyId="accessKeyHere"
  aws.secretKey="secretKeyHere"

Previously, you could get these keys from your root account in Amazon but, for security reasons, a few weeks ago they started to force you to follow a new process to configure your keys. You have to use the Identity and Access Management (IAM) and create your keys. They suggest that you create a pair of keys for each kind of user that your application has. The choice is yours 🙂

Now let’s take a look in the code necessary to upload a file.

    val result:Future[Unit] = bucket + BucketFile("pdfs/yourfile.pdf",
      "application/pdf",IOUtils.toByteArray(new FileInputStream(pdfFile)),Some(PUBLIC_READ))

There are a two important objects here. Bucket and the BucketFile. The first is needed to identify which folder(bucket) contains all your uploaded files from your current application. It is easy to create this object.

    private val bucket = S3("youpet")

Probably you will create one bucket per application.

The BucketFile is just a wrapper with all information needed about your file being uploaded. The last parameter is a little bit important. It is recommended to pass which roles this file has. Here we are saying that everyone can read(download). All this code can be encapsulated in a Scala class that can be used from your Java code :).

    object AmazonS3 {
      private val bucket = S3("youpet")

      def upload(folder: String, file: File,fileName:String): WaitingForS3 = {
        val timestampedName = FilenameUtils.getBaseName(fileName)+"_"+System.currentTimeMillis()+"."+FilenameUtils.getExtension(fileName)
        val s3Url = bucket.url(s"${folder}/${timestampedName}")

        val result:Future[Unit] = bucket + BucketFile(s"${folder}/${timestampedName}",
          extractMimeType(fileName),
          IOUtils.toByteArray(new FileInputStream(file)),Some(PUBLIC_READ))

        result.map { unit =>
          Logger.debug(s"Enviou o arquivo $s3Url")
        }.recover {
          case S3Exception(status, code, message, originalXml) => Logger.info("Error: " + message)
        }

        new WaitingForS3(s3Url,result)
      }
    }

This same code is available here. Feel free to copy and use in your projects :). Of course you could use all these Scala classes from your Java code directly but, in this case there are “functions as parameters” and “case classes” that are hard to translate to Java code. It is better isolate this code in a Adapter class and only expose a simple method to your Java side.

That is it! Upload your files to S3 and just have to deal with the links of your uploaded files :). It is easy to maintain and you gain, as a bonus, things like cache out of the box :).

Composable pages and the Cache feature

The Cache feature provided by Play, in both versions, is very well known. It is so important, that has its own page in the documentation. Just to give a quick description. Once you have put the @Cache annotation in your action, after the first request, the html generated will be stored and reused for the consecutive requests. The same thing applies to the Scala version.

The downside of this approach is that, almost every page in our application, has a relation with the current logged user. So, if you put the name of the user in the home page, like in GUJ(brazilian java forum), you just lost the opportunity to use the cache feature. You always have to remember, this cache is global. One approach could be create cache entries related with the current user, but this will imply an explosion of entries in the cache implementation.

In one of my posts, that was related with the Big Pipe idea presented in the talk given by Linkedin, it was demonstrated how you can compose your pages, loading each piece from a different request. Something like Page as a Service :). If you follow this approach you can gain another thing, the ability to cache just certain pagelets from your page!

Let’s see how we could compose the home page of GUJ using the “big pipe” approach implemented by Linkedin.

    public static Result index() {
      F.Promise news = ServiceClientJ.makeServiceCall("recent/news");
      F.Promise recentTags = ServiceClientJ.makeServiceCall("recent/tags");
      F.Promise availableJobs = ServiceClientJ.makeServiceCall("jobs");
      F.Promise infoqNews = ServiceClientJ.makeServiceCall("infoqnews");

      F.Promise newsHtmlPromise = render(news, views.html.guj.news.f());
      F.Promise recentTagsHtmlPromise = render(recentTags, views.html.guj.recent_tags.f());
      F.Promise availableJobsHtmlPromise = render(availableJobs, views.html.guj.jobs.f());
      F.Promise infoqNewsHtmlPromise = render(infoqNews, views.html.guj.infoq_news.f());

      HtmlStream newsStream = Pagelet.renderStream(newsHtmlPromise, "news");
      HtmlStream recentTagsStream = Pagelet.renderStream(recentTagsHtmlPromise, "recentTags");
      HtmlStream availableJobsStream = Pagelet.renderStream(availableJobsHtmlPromise, "availableJobs");
      HtmlStream infoqNewsStream = Pagelet.renderStream(infoqNewsHtmlPromise, "infoqNews");

      HtmlStream body = HtmlStream.interleave(Arrays.asList(newsStream, recentTagsStream,availableJobsStream,infoqNewsStream));

      return ok(HtmlStream.toChunks(views.stream.guj.index.apply(body)));
    }

As you can see, the page is built based on several requests! If you, for example, want to cache the “recent tags” pagelet, just put the @Cache annotation in this controller’s action.

    public class RecentTags extends Controller{

    	@Cached(key = "recent_tags", duration = 3600)
    	public static Result index(){
    		return ok(views.html.tags.index.render(tags.top()));
    	}
    }

Now you are taking advantage of the cache feature! I really like this approach and I will try to use it in my next projects :).

Accessing url parameters as get parameters in Play

A few weeks ago, I published here a post explaining my approach to implement a multi tenant strategy in my application. My main problem was that I did not have access to the url parameters in order to extract the tenant id. Play does not provide any easy way to access this information. So I kept searching and I found one solution, not to pretty, but functional! Just to remember, here I have my action.

	public class TenantResourceAction extends Action{

		@Override
		public Promise call(Context ctx) throws Throwable {
			Long id = Long.parseLong(ctx.request().
					  getQueryString("clientId"));
			//do your stuff here
			return delegate.call(ctx);
		}

	}

The getQueryString(“clientd”) method does not return the value because, as explained here, Play’s team decided do not insert url parameters into the querystring parameters map. So I need to extract the client id from almost every url. For example, http://localhost:9000/user/3/photos. It’s mandatory to check if the current logged user owns the requested resource. To solve this issue was necessary to use some classes from Play core, what was nice to learn more about the tool that I use a lot :). The first part of the job was to extend GlobalSettings and override the Play’s default behavior.

	import play.GlobalSettings
	import play.api.{ GlobalSettings => ScalaGlobalSettings }
	import play.api.mvc.RequestHeader
	import play.api.mvc.Handler

	object Global extends GlobalSettings with ScalaGlobalSettings {

	  //overrided because it was generating a conflict
	  override def getControllerInstance[A](controllerClass: Class[A]) = controllerClass.newInstance();

	  override def onRequestReceived(request: RequestHeader): (RequestHeader, Handler) = {
	    val (rh, handler) = super.onRequestReceived(request)
	    val route = rh.tags("ROUTE_PATTERN")
		...
	  }

	}

Here I had too choose Scala because was necessary the usage of the tags method from Scala version of RequestHeader. This method contains some meta information created by Play during the processing of parsing a request. This is the case of ROUTE_PATTERN key. This key returns the configure value from your routes file that was used to handle the current request. Now that we have the route, for a given uri we have to be able to retrieve all dynamic and static part from this uri. This is the hardest part, because we have to deal with some hidden parts of Play :). When you download the source code of the project, you will see that there are a several projects. One of them is the Routes-Compiler, which is responsible for create the object that represents a parsed route. The class of this object is play.router.PathPattern.  Take a look at the code needed to build this object.

	package play.router

	import play.router.RoutesCompiler._

	object RoutesCompilerHack {

		lazy val parser = new RouteFileParser

		def transform(verb:String,path:String):PathPattern =
				parser.parse(s"$verb $path  fakepackage.fakecontroller.fakemethod")
				.get.head.asInstanceOf[Route].path
	}

In order to have this code working, I had to put it in a package called play.router. The RouteFileParser is a private package class and can’t be accessed outside. Essentially, it is hack :(. After that, is necessary to convert the current PathPattern object to a play.core.PathPattern, which has a method that receives a uri and returns the bound parts with their respective values.

	import play.router.RoutesCompilerHack
	import play.core.{ PathPattern => PlayCorePathPattern }
	import play.router.PathPart
	import play.router.DynamicPart
	import play.router.StaticPart
	import play.core.{DynamicPart => CoreDynamicPart}
	import play.core.{StaticPart => CoreStaticPart}

	object TentantIdExtractor {

	  def apply(confRoute:String,uri:String):String = {
            //here could be used some cache 🙂
	    val pathPattern:play.router.PathPattern	 = RoutesCompilerHack.transform("GET", confRoute)

		//Dynamic and Static objects used inside the Router compiler project
	    val routerCompilerParts = pathPattern.parts

		//Transforming them to play.core.Part(Dynamic and Static)
	    val coreParts = routerCompilerParts.map { part =>
	      part match {
	        case DynamicPart(name, constraint, _) => CoreDynamicPart(name,constraint,true)
	        case StaticPart(name) => {
	          //the first slash("/") was not being generated
	          if(name.startsWith("/")) CoreStaticPart(name) else CoreStaticPart(s"/$name")
	        }
	      }
	    }

		//build the play.core.PathPattern
	    val corePathPattern = PlayCorePathPattern(coreParts)

The objects DynamicPart and StaticPart are used internally in Play to represent the url parts. Now, that we built the play.core.PathPattern object, it is possible to query this object with a requested uri and to retrieve a Option object with the values.

     val result:Option[Map[String,Either[Throwable,String]]] = corePathPattern(uri)

This monster object, that could be encapsulated in some class, has all the dynamic values passed by client. Now we can search for some variable and get the value!

	result.get("clientId") match {
	    case Right(value) => value
	    case Left(e) => throw e
	}

To finish our job, we now can get this value and push into query parameters!

	override def onRequestReceived(request: RequestHeader): (RequestHeader, Handler) = {
	  val (rh, handler) = super.onRequestReceived(request)
	  val route = rh.tags("ROUTE_PATTERN")
	  val tenantId = TentantIdExtractor(route,request.uri)
	  val newParams = rh.queryString.+("clientId" -> List(tenantId))

	  val newRequestHeader = rh.copy(rh.id,rh.tags,rh.uri,rh.path,rh.method,rh.version,newParams,rh.headers,rh.remoteAddress)
	 (newRequestHeader, handler)
	}

We pushed the id and rebuilt the RequestHeader to make this new parameter available to be accessed through request.getQueryString(“clientId”). The code is available here and you can use in your multi tenants projects! That is it folks. I hope this has helped you to understand a little bit more about Play internals and how important is to know the tool that you are using. And please, if there is an easier way, let me know. I enjoyed to hack the framework but I prefer an easier code 🙂

Organizing composable Play apps with Flexbox

Yevgeniy Brikman made a awesome presentation about how Linkedin solved its problems to build complex web pages. The basic problem is that, for instance, your profile’s page is too complex and keep one single file like a jsp, to build all this html, is not maintainable. Obviously, we are thinking in a long running app.
There are a lot of objects that have to be loaded to create that page. For example:

  • Basic information like: name, current company, etc.
  • Background information
  • Skills and Endorsements
  • Education
  • People also viewed

This is a major problem for all big web sites and each one has its own version of solution. A lot of them, load the snippets of page from iframes and with this, they can load these pieces from everywhere they want… Another approach is when the server sends a almost blank page and every snippet is loaded from ajax calls. Both approaches solve the problem but it delegates a lot of responsibility to the browser.

The third possibility, which is more difficult, would be load all snippets in your server side and glue them to build the requested page. Using this approach, even in a synchronous way, you would have just small pages that are more testable, easier to maintain and would send to browser just a simple html. Facebook engineers wrote about that in this amazing post.

Linkedin guys used this same approach to change the way them build web pages. They used Play’s API to fetch small pieces of html and aggregate these snippets to compose the page. But if you remember, Play is all about async and streaming data. So Linkedin went ahead and used this power to fetch all pagelets in async way, using the Promise’s API provided by Play. Now, and if the last Promise completes its job before the first one, what your controller would have to do? Wait for the first? The answer is no! If you have a partial of your html, just send to the browser :). To accomplish this task, they used the Iteratee and Enumerator API to stream each html partial as soon as it is available. This project is hosted on github(link aqui) and I advise you to take a serious look!.

Everything is really cool until now, but how they organize all pagelets to build the page? I mean, there is a order between Background information’s block and Education’s block . They solved this using a simple Javascript snippet inside pagelet’s template. Take a look:

    @(contents: Html, id: String)

    <script type="text/html-stream" id="@id-contents">
      @contents
    </script>

    <script type="text/javascript">
      document.getElementById("@id").innerHTML = document.getElementById("@id-contents").innerHTML;
    </script>

Each pagelet knows what is its id in the main template. So, it is used javascript to put the returned html in the correct place, smart :). Talking with @sergio_caelum and @srsaude, masters in frontend topic, they warned me about the high cost that is to use innerHtml in your browser. Especially if you have to use it a lot of times! So they proposed to me that would be interesting if the Linkedin had used the Flexbox property in CSS3. This property, allows you rearrange every element in your page with CSS, no Javascript is needed. I liked the idea so I forked the code and I made this little change.

Now, each snippet has its own div and I just have to define the appearance order in the CSS file :).

    @(wvypCount: Int, searchCount: Int)

    <div class="wvyp">
      <h2>Who's Viewed Your Profile</h2>

      @views.html.wvyp.wvypCount(wvypCount)
      @views.html.wvyp.searchCount(searchCount)
    </div>

And now the css code:

    .wvyp {
    	display: -webkit-flex;
    	display: flex;
    	-webkit-flex-flow: column;
    	 flex-flow: column;
    }

    .wvyp .wvyp-count {
    	color: #0077b5;
    	-webkit-order: 1;
    	 order: 1;
    }

    .wvyp .search-count {
    	color: #333;
    	-webkit-order: 2;
    	order: 2;
    }

Now, I can even delete the pagelet template file :). This changed version is in my repository, go there and take a look!.

I really like this idea and I wish to have a chance to apply this solution in one of the systems that I am helping to build. What did you think? I had to write this post because this presentation is one of the best that I ever saw :). I don’t remember when I spent 50 minutes watching a video!

 

 

 

Play 2.3, Java 8 and async results

For the Java developers, Play 2.3 greatest feature is the native support for Java 8 and all things that are possible with lamba support.  Almost all pieces of code that were built with anonymous classes now can be replaced with lambdas.

Let’s see the case when we want to return a async result. The older version is like this:

    Promise<List<Photo>> promise = Promise.promise(new Function0<List<Photo>>() {

    	@Override
    	public List<Photo> apply() throws Throwable {
  		  return JPA.em().createQuery("select p from Photo p",Photo.class)
  		  .getResultList();
    	}
    });

    return promise.map(new Function<List<Photo>, Result>() {

    	@Override
    	public Result apply(List<Photo> photos) throws Throwable {
    		Html render = views.html.photos.render(photos);
    		return ok(render);
    	}
    });

The new version with lambdas is way more cleaner.

    Promise<List<Photo>> listingPhotos = Promise.promise( () -> {
    	return JPA.em().createQuery("select p from Photo",Photo.class).getResultList();
    });

Remember, all methods that receive functional interfaces(interfaces with just one method) can be used passing lambda as arguments!

And here, we didn’t separate our code like we should. Database access is being done in our controller. If we put this code in a different class, we can improve the usage of promise.

  Promise<List<Photo>> listingPhotos = Promise.promise(Photos::all);

Method Reference is a great feature to use with lambdas, the code is much more cleaner. Now you have to use map method to transform the Promise<List<Photo>>  to Promise<Result>.  This will be a common situation around your application.

    return listingPhotos.map((photos) -> {
    	Html render = views.html.photos.render(photos);
    	return ok(render);
    });

Here we can try to be more creative. I would like to use Method Reference to create Promise<Result> rather than use the map method. It would be nice if we had used a pimped version of Promise class with statuses map method. Here a example:

    return new PimpedPromise<List<Photo>>(listingPhotos).
            map(Controller::ok,views.html.photos::render);

There is nothing out of the box in Play so, to accomplish this, we can create our pimped version! Take a look:

    public class PimpedPromise<T> {

    	private Promise<T> promise;

    	public PimpedPromise(Promise<T> promise) {
    		this.promise = promise;
    	}

    	public <B extends Content> Promise<Result> map(play.libs.F.Function<Content, play.mvc.Results.Status> statusFunction,Function<? super T, B> callback) {
    		Promise<B> contentPromise = promise.map(callback);
    		return contentPromise.map(content -> {
    			return statusFunction.apply(content);
    		});
    	}

    }

We just changed a little bit the signature of map method :). We forced the developer to pass a function(second argument) that returns a Content object. Then we get the result of promise.map and we have to map again using the status function(first argument). Maybe it is a little bit complicated inside our pimped promise but is, at least for me, better to be used in controllers.

What do you think? Have you tried to create something new with the lambda support?

Multi tenant approach with Java 8 in a Play project.

In my current project, I had to implement a multi tenant approach. There is nothing new about this, I have to check if current user is the owner of some resource. And I have to do the same thing across other several actions. The best way to do this, is to build an Action composition and compose all actions with it. So, let’s say we have this route:

   /admin/users/update/:id

Now, when we try to access this resource, our interceptor will be invoked:

    @Override
    public Promise<SimpleResult> call(Context context) throws Throwable {
    	RoleType currentRole = CurrentUser.role();

    	Long currentLoggedUserId = CurrentUser.id();
    	Long clientParamId = //get parameter here;
    	for (RoleType roleType : rolesAllowed) {
    		if(roleType.acceptsRole(currentRole)
    		&& roleType.acceptsTenant(currentLoggedUserId,clientParamId)){
    			try {
    				return delegate.call(context);
    			} catch (Throwable e) {
    				throw new RuntimeException(e);
    			}
    		}
    	}
    	return Promise.<SimpleResult>pure(
    	  Controller.unauthorized("You are not allowed to see this page"));
    }

And now we have a problem. How do we extract the client id from the url? The first thing that I thought was: All parameters are in request data…

  Long clientParamId = Long.parseLong(context.request()
                     .queryString().get("clientId")[0]);

Unfortunately, Play does not provide this information anywhere :(, if you try to run this code, you will get a NPE. This probably happens because in Scala version you would not have this problem, in there you compose actions in a different way. Basically you can invoke the “call” method from your controller’s action, using the functional support provided by the language instead of using annotation. You can see more here(link). To solve my problem, I used the same approach. Let’s see:

    public static Result updateForm(final Long id) {
    	return new RoleAction(User.class, id, RoleType.ADMIN,RoleType.TENANT)
    			.call(new Function0<Result>() {
    				public Result apply() throws Throwable {
    					User user = JPA.em().find(User.class, id);
    					Form<User> filledForm = userForm.fill(user);
    					return ok(views.html.admin.users.update_form.render(filledForm));
    				}
    			});
    }

It is a little bit verbose, no doubts, but I needed to delivery this feature :). And now I can access all parameters that I need. Just to make the job less annoying, I’ve created a Eclipse template that allows me just write “roleAction” and the code template is generated automatically :).

The good thing about this approach is that, now with Java 8, we can change this implementation in order to use the new lambda support :). Play with Java8 is a lovely thing!

    return new RoleAction(User.class,id,RoleType.ADMIN,RoleType.TENANT)
   .call( () -> {
    	User user = JPA.em().find(User.class, id);
    	Form<User> filledForm = userForm.fill(user);
    	return ok(views.html.admin.users.update_form
    			.render(filledForm));
    });

What do you think? One nice thing here is that I didn’t need to change the original call method. When you have just one method in your interface, the new compiler understands this interface as a Functional Interface and allows you to pass lambda as a parameter. Java 8 support is enabled in Play 2.2.2 and Play 2.3.x!

One model, many validations

It is not unusual a application has more than one html form that should be bound with the same model. Think about this situation: you have a form to register a new user with just a few fields, like name, email and password. After that, you need this same user completes his registration with other fields.

This common situation puts you in a problem. How to partially apply a validation rule in the same model. Below we have the User class:

    package models;

    @Entity
    public class User {

    	private String id;

    	@Required
    	private String name;

    	@Required
    	private String email;

    	@Required
    	private String password;

    	@Valid
    	private Address address = new Address();

    	@Required
    	private String facebookId;

    	//getters and setters
    }

There are a lot of validations! In the first situation, you only need to validate three fields. Let’s see the code:

    public static Result create(){
    	Form<User> filledForm = newUserForm.bindFromRequest("name","email","password");
    	if(filledForm.hasErrors()){
    		return badRequest(views.html.new_user_form.render(filledForm));
    	}
    	User user = filledForm.get();
    	//Ebean.save(user);
    	return redirect(routes.UsersController.form());
    }

Here we allow only the name, email and password are linked to the model. I already commented this in other post. The problem is when we invoke hasErrors method. This method will return true, because our model has other validations. Here we can use a feature provided for Bean Validation that allow us to split validation in different groups.

    package groups;

    public interface ValidationGroups {

    	public interface SocialInformation {}
    	public interface UpdateInformation{}
    	public interface BasicInformation{}

    }

The nice thing about this is that Play’s validation follows Bean Validation spec. We can take advantage of this! We only need to pass the group when we create the Form object.

         private static Form<User> newUserForm = Form.form(User.class,ValidationGroups.BasicInformation.class);

That is it! You can have a lot of groups and use them in specific situations. You still can use multiple groups to perform a validation :).

    @Required(groups={ValidationGroups.BasicInformation.class,ValidationGroups.SocialInformation.class})
    private String email;
    @Required(groups={ValidationGroups.BasicInformation.class,ValidationGroups.SocialInformation.class})
    private String password;
    @Required(groups=ValidationGroups.SocialInformation.class)
    private String facebookId;

And now you pass a different group to form method.

    private static Form<User> newUserForm = Form.form(User.class,ValidationGroups.SocialInformation.class);

Name and email will be validated when a validation is performed with one group or another.

Another alternative, that I try to avoid, is to create a new class that represents your html form. You can use it to bind input values and after that, create your Model. This approach is better when you have a form that is not bound with any model. For example, a form to log in your user. In this case, you can use DynamicForm or a Class that represents login information.

If you have any doubt about PlayFramework, fell free to get in touch. My contact informations is here.

 

Playframework, how to protect against Mass Assignment

Form data handling is one of the most used feature in every MVC framework, in Play is not different. Documentation on website is very good, but leaves outside a couple of important situations. Let’s see a first case to better understanding about this feature.

Imagine a simple html form to register a user. Here is the user class and template which contains html form:

      public class User {

      	private String id;
      	private String email;
      	private String password;
      	private RoleType roleType = RoleType.CUSTOMER;

      	public void setRoleType(RoleType roleType) {
      		this.roleType = roleType;
      	}

      	public RoleType getRoleType() {
      		return roleType;
      	}

        //getters and setters for other fields
      }

Now we have to write a controller to handle the client submission. Here is an example:

    public class UsersController extends Controller{
	
    	private static Form<User> newUserForm = Form.form(User.class); 

    	public static Result form(){
    		return ok(views.html.new_user_form.render(newUserForm));
    	}
	
    	public static Result create(){
    		Form<User> filledForm = newUserForm.bindFromRequest();
    		if(filledForm.hasErrors()){
    			return badRequest(views.html.new_user_form.render(filledForm));
    		}
    		User user = filledForm.get();
    		Logger.info("RoleType {}",user.getRoleType());
    		Ebean.save(user);
    		return TODO;
    	}
    }

The problem is that we are believing that our user will simply fill the inputs in form and submit the information. What if an extra parameter appear in our Form object? For example, “user.roleType“. There are all kinds of user in this world, and maybe one of them likes to test your application trying to submit extra parameters, using chrome tools for example :).

editiing_html_chrome

When you invoke form.bindFromRequest().get, Play’s underlying binder will get all parameters and try to set in your User object. Every field that has a setter can be set with a form parameter. So the first solution would be drop setRoleType() method from your class. But in our case that is impossible, we need this setter there to allow admin changes roleTypes of other users.

One other solution is configure Form object to accept only some fields, and this feature is implemented already in Play Framework.

    public static Result create(){
    	Form<User> filledForm = newUserForm.bindFromRequest("email","password");
    	if(filledForm.hasErrors()){
    	    return badRequest(views.html.new_user_form.render(filledForm));
    	}
    	User user = filledForm.get();
    	Logger.info("RoleType {}",user.getRoleType());
    	Ebean.save(user);
    	return TODO;
    }

Usage of this technique is a nice way to protect your system against Mass Assignment attack. For instance, Github already suffered with this kind of attack. Stay connected, next week I will write how to handle different types of validations from the same model!

Your Play project is Java and Scala, at the same time

In the moment of creation a Play application, we are obliged to choose between Java and Scala as the base of our code, which is good because you can prefer one or another. The problem with this choice is that the programmers, basically Java programmers, they think that is a final choice. It is not unusual see some doubts in Play’s user forum about how to do something in Java version which is already well know in Scala version. For example, how to implement Web Sockets.

Of course, if there is a Java way to accomplish the task, go ahead and use it but, if there is not a Java way or this way is worst than the Scala version, still go ahead and use Scala. This is the point of this post, Play is possibly the only framework thought to be used with Scala and Java together, and not separated. Another example, all view templates are written in Scala. You still have the router file :).

Let’s see some examples! The first one is if you need to receive a Option in your template. You can try to pass a Option from play.libs.F.Option to your template.

    @(maybeTag:JavaOption[Hashtag])

    @maybeTag.map { tag:Hashtag =>
          @tag
    }.getOrElse {
          tagless
    }

The problem is that template, that becomes a Scala class after compilation, does not have any conversion from play.libs.F.Option to scala.Option. So code showed above will not work. There is no problem at all, instead of pass Play’s wrapper as argument, you can create a new Scala Option and solve your problem.

    ok(views.html.index.render(scala.Option.apply(hashtag)));

Another situation. Sometimes you have a class that simply holds a value. For example, in one of my current projects, I have a class called ImportStat.

    public class ImportStat {

    	private Number count;
    	private PhotoStatus photoStatus;

    	public ImportStat(Number count, PhotoStatus photoStatus) {
    		super();
    		this.count = count;
    		this.photoStatus = photoStatus;
    	}

    	public Number getCount(){
    		return this.count;
    	}

    	public PhotoStatus photoStatus() {
    		return photoStatus;
    	}

    }

I need to print the count value to give some information about a task that is being done by some Actor in my system. One way to do this is:

    @for(stat <- stats) {
     	  @stat.photoStatus():@stat.getCount()
    }

But, with a minor change you can take advantage of Scala syntax sugar to return values of your objects. You can use the apply() method. So let’s change our class.

    public class ImportStat {

    	private Number count;
    	private PhotoStatus photoStatus;

    	public ImportStat(Number count, PhotoStatus photoStatus) {
    		super();
    		this.count = count;
    		this.photoStatus = photoStatus;
    	}

    	public Number apply(){
    		return this.count;
    	}

    	public PhotoStatus photoStatus() {
    		return photoStatus;
    	}

    }

Now, in your template, you can write something like this.

    @for(stat <- stats) {
     	  @stat.photoStatus():@stat()
    }

The last one is the better, at least for me. I needed to use SSE to push notifications to browser. I googled about it and found this link, there was not a Java version! So I kept looking for and I found this blog post, which showed to me that Scala version was already implemented and it is much better than Java way, even if you use the pull request that brings SSE to Java version. So, for this case, I preferred to write the controller in Scala. Let’s just take a look in how you can open a SSE connection.

    package controllers

    //imports

    object UpdatePhotosController extends Controller {

      val (chatOut, chatChannel) = Concurrent.broadcast[JsValue]

      def newPhotos() = Action {
        implicit req =>
          {
            Ok.feed(chatOut &> EventSource()).as("text/event-stream")
          }
      }
    }

Now, let’s look how you can push information through the channel. And we will make this from an Actor written in Java!

    public class UpdatePhotoPanelActor extends UntypedActor{

    	@Override
    	public void onReceive(Object message) throws Exception {
    		final String id = (String) message;
    		Photo photo;
    		try {
    			photo = JPA.withTransaction(new Function0() {

    				@Override
    				public Photo apply() throws Throwable {
    					return Photos.byId(id);
    				}
    			});
    		} catch (Throwable e) {
    			throw new Exception(e);
    		}

    		UpdatePhotosController.chatChannel()
    		    .push(PanelPhotosJson.toScalaJsValue(0,photo));
    	}

    }

That is it! Don’t be afraid to mix both languages. If you are in Java project, your code will be 90% in Java and just 10% in Scala, not a big problem. The important part of Play written in Scala is the core, to build real world application is not important which one you gonna pick :). Choose the option that better fits to your team.