Thursday, February 28, 2013

Using Deadbolt for Authorization in Your Play 2 Site With Scala

I needed security in my site. I needed a feature that would guarantee for only authorized users to go into some of the controllers (links) of my site. For non-registered users, I wanted to display a "non authorized" page so they could either login or register. I also needed for Play 2.1 using Scala 2.10. My search lead me to deadbolt 2 (D2). In this post I will cover the following:

  • How to include deadbolt into your Play site
  • Create a security service to validate registered users
  • Send non-registered users to a "not authorized" page
  • Add security to your controller
  • How to validate registered users from the template

Include deadbolt into your Play site

The first thing that you need is to include the deadbolt plugin into your site. You need to include it inside your project/Build.scala. Here you will find that I added the play-plugin-mailer already, postgresql, and finally deadbolt. I had to include the resolvers for the application to work.

Add Security Service to Your Application

Before you implement the service, you need to create a subject. Subject is what determines a user in deadbolt. It also handles privileges such as roles and permissions. Below is the code for a User inside the app/models package:

Now, that we have a subject, we need to implement the DeadboltHandler to validate registered users/subjects and to send the non-register users to a "non-register" page. The main application that takes care of user validation is the getSubject.

Here the code tries to get the the username from the HTTP session, and in case there is a user, return a subject (User) with that session name. Otherwise, return a "None". When returning None, Deadbolt automatically knows that this is not a valid/registered user.

Send Non-Registerd users to a "Non-Registered" Page

For those users that are not registered (None Subject), the "onAuthFailure" will take effect.

Below is the code inside the app/security package.

Add Security to the Controller

Now, that the DeadboltHandler is implemented, you have to make some decisions based on the business rules of your site. For example, if you have an Contact Directory page where only registered users could see it, you need to assure that there is a Subject (registered user) present.

Noticed that I am also passing a new MyDeadboltHandler to the page. This is because I also need to implement some business rules inside the template. In this site, I needed to show a "Login" link for those non-registered users or display a "Contact Directory" and a "Logout" link for those authenticated users. Below is my navigation template.

Inside the "subjectNotPresent" we will handle the case when the user is not logged in. Whereas, in the subjectPresent we will show the Logout and the Contact Directory link pages.

For those controllers that doesn't require the a subject to be present, I still had to pass the implemented deadbolt handler because it had to be in every one of my pages. This is to validate if the user is authenticated.

Friday, February 22, 2013

Non-Blocking Async with Scala 2.10 and Play 2.1

In my application, I needed to consume an "expensive" (+3 seconds to respond) web service. The results had to be as fast as possible without halting the system/process. What I needed, was to process the web service in the background (thread), then display the results in the application. I used Twitter and GitHub as an example.

Then display the results with the following render.scala.html page:

At the beginning of the application, I got the following error:

The solution is to import the following:

Wednesday, February 20, 2013

Working With Nested Forms with Play 2.1

When creating nested forms and modifying input parameters into a Play 2.1 application seems simple, in many occasions it can be confusing. Here is an application with a model named Hedger which has a object named MarketData. In here I will try to explain the following:
  • How to handle a nested form inside the controller
  • How to configure the nested form in the view page
  • Create custom validations with Play 2.1 form

The first thing that we will show is the model objects - Hedger and MarketData

Now, we will create the form inside the controller

Noticed that there is a "sixMonth" and a "year" field in the form. These two fields are bind with the MarketData object. Therefore, we need to bind the input parameters into the case class. However, the object accepts Double and the form has "text". To handle this, we used a custom validation by using "text.verifying". The verifying contains two parameters:

  • Error message
  • Boolean validation that there is an error - isInvalid

The Hedger.validateDouble has the following code

You can also do the match inside the form, but I did this to make the code cleaner and to show that you can do the checking inside the object

When binding the object, you need to take care of the "apply" and "unapply". In the apply section, you need to show the mapping of the Hedger object, but since this is a nested form, you also need to take care of the MarketData as we saw in the previous code.

Here is the view page for the application:

Thursday, February 7, 2013

Scala problems - using List

Trying to better my Scala programming by trying some examples/questions of the rich collection API.

How to shuffle a list of strings:

Tuesday, February 5, 2013

Problems brew install - could not link [app]

My favorite command to install application in mac is homebrew. Today I was getting the following error when installing scala:

The solution is to make the directory as a member of my username

Monday, February 4, 2013

Send e-mail using Play 2, Scala, and Emailer pluggin

I needed to send an e-mail when a user fills up a contact form. Below is the how I implemented the application using the mailer plugin.

First, we add the e-mailer library: projects/Build.scala

Then, we add the play plugin conf/play.plugins:

Now, you need to add the smtp host in conf/application.conf:

Now, we add the service:

From the controller, then I access this service:

It is using the Contact model which has the following fields:

The application needs to import the following:

Then, you can start building you e-mail service by using:

Where all the messages are stores in the conf/messages

Friday, February 1, 2013

Using forms with Play framework 2 and Twitter's Bootstrap

I've been trying to learn Twitter's Bootstrap, Play2, and Scala for the past month. The past two days, I've been trying to create a basic HTML application along with a controller, model, persistant layer, and HTML form. It took me a bit of time to really understand what was going on, but I think I finally got it. The form is a basic "Contact Us" and here are the requirements:

  • User should prompt to enter a contact form: name, e-mail, phone, and comment
  • Form should validated any errors and report a friendly message in case of such error
  • Display a message back to the user that the information was indeed saved

Here is what my controllers will have:

  • A form with all the validation
  • A controller that will take the user to the form page
  • A controller that will validate the form, and either send it back to the form's page in case of an error, or display a successful messages in the details page
  • A controller that will act as an "edit" page, which displays the form information successfully saved

First, lets start with the form. We have a "contactForm" which only needs to have:

  • Client's name - required field
  • Client's e-mail - required field and validates if it's already in our contact list
  • Client's phone number - required field
  • Comments - anything that the client can tell us about his/her firm and reason of reaching us

However, the model that we have, needs to have more than these fields. For example, we need to have an ID, and also a signed-up date that tell us when the customer registered with us.

The model application will look like this:

However, because the id, comments, and signedup fields are not required, we need to add Scala's "Option" field. The reason of this wrapper is to avoid "nulls". This tells the application that the field is not required and that it might be null. This will also come in hand with our SQL and with the form fields in the controller. Here is how the model will look like:

Now, we need to take care of the persistent layer (DAO/Repos). This layer will take care of displaying all the contacts, retrieve contact by e-mail, and insert a contact into our database.

For this example, I will be using the h2 database provided by the Play framework. You need to comment the following lines in the conf/application.conf

Since, I will be using Anorm, we need to create the SQL script for your SQL evolutions. You need to create a folder "conf/evolutions/default" and add a file 1.SQL with the following code:

Now, we can create the rest of the model:

Inside the object method, you will find the simple mapper. This is simply mapping each of the SQL record. It is important to be consistent with the case class. The method's purpose can be seen in the findAll implementation. The application will respond with a sequence of contacts, by executing an SQL statement, and calling the simple to all records (hence the "*") to be map using the "simple" mapping.

The findByMail is a bit different. The main purpose of the method is to find out if there are no records for this e-mail. To avoid null or empty validations, it's recommended to use Scala's "Option" wrapper. This is why we will add the Option[Contact] as our return statement, and the "headOption" when returning the response. This will be very helpful for our form as we will see next. Otherwise, you will get errors similar to this one:

Now that we have our model and persistent layer, here is the controller code:

As you can see, the form will be doing the validation for each field. Here's is where I failed: I was under the impression that I should only have the fields that were in my form. It so happens, that the Contact.apply and Contact.unapply is mapped to the case class; therefore, you need to specify all the fields. This type of error caused the following message:

Now, for the validation, we need to add is the id as optional since this will be given by the DB when creating the record. Next is the e-mail validation. As requested, there needs to be a validation in case the e-mail has been recorded previously, and return a friendly error message. The email calls a "verifying" method that takes two parameters. One is the error message in the case that the field is not valid. The second parameter is a boolean that checks the validity of the value. In the case of the e-mail, we check if it's in the database - "Contact.findByEmail(_).isEmpty". The "isEmpty" method is provided by "Option" wrapper - in case if it's null or empty, it will be true.

The "newContact" controller will take care of displaying the form. It also sends the form back in case there are any errors. This is why we add the "implicit request". We will be using the flash for a temporary storage of the error.

Most modern web-frameworks have a flash-scope. Like the session-scope it is meant to keep data, related to the client, outside of the context of a single request. The difference is that the flash-scope is kept for the next request only, after which it's removed. This takes some effort away from you, as the developer, because you don't have to write code that clears things like one-time message from the session.

Play implements this in the form of a cookie that's cleared on every response, except for the response that sets it. The reason for using a cookie is scalability. If the flash is not stored in the server, each of one of a client's requests can be handled by a different server, without having synchronize between servers.The session is kept in a cookie for exactly the same reason. This makes setting a cluster a lot simpler. You don't need to send a particular client's request to the same server, you can simply hand out requests to servers on a round-robin basis.

Now, lets look at the "create" controller. This will be the action called by the form. The application will get the HTTP request, and bind the request. Then, it will call the fold command to see if the form values have errors or if it's successful. In Scala "fold" is often used as the name of a method that collapses (or folds) multiple possible values into a single value. The fold method has two parameters, both of which are functions. So, "hasErrors" is called if validation failed, and "success" if it validates without errors

Below is the contact.scala.html code:

As I mentioned at the beginning, I'm using Twitter's Bootstrap to handle all the CSS and HTML5 goodness. Therefore, I want to leverage as much as possible all of that. To activate the CSS handling and using the helper functions for Play you need to import a few fields. Also, you need to add the form and flash scope parameter to the HTML. I also used the implicitFieldConstructor to show where the errors happened. We will show that later. First lets emphasize on the form. The actions for the form will be handle by "@helper.form(action = routes.ContactUs.create, 'id -> "validForm")". Then, we will add the fields by using the "fieldset". I wanted to leverage the uses of place holder, labels, and classes on all the input fields. However, the most important part is to know that @helper.inputText(contactForm("name")) consists on the name of the input. The id goes inside the "contactForm".

I also provided some type of error friendly validation in case the user has some erroneous fields. I created a "contacterror.scala.html" with the following code:

Then, I added the @implicitFieldConstructor = @{ FieldConstructor(contacterror.render) } in the form (contact.scala.html). Again, this way, we will see the highlights and the friendly errors on the fields.