Author Archives: Krishna

About Krishna

Applications for social medium

Java to JavaScript journey

Being a Java guy, I started off spending time understanding what are good web frameworks for someone with strong Java background. In the beginning of my journey, I hated Javascript as I hate seeing famous “undefined” errors in browser, but that somewhat changed in the end. For most of my learning, I wanted to stick with current bestpractices/tools like Bootstrap, HTML5, Responsive Webdesign (RWD), Single Page Application (SPA), Model View View Model (MVVM)

Let me start with Java world:

In Java world, there are 2 competing frameworks where you can pretty much do all the best practices of web development like HTML5, Bootstrap, RWD, SPA. Vaadin (www.vaadin.com), ZKOSS (www.zkoss.org). Both take different approaches. Vaadin is built heavily on GWT (http://www.gwtproject.org/) and it is 100% java code including frontend markup. Vaadin 7 the latest edition has a poor support for CSS. I liked ZKOSS a lot.

  • It has a nice blend of markup and Java support,
  • it has good support for CSS (SCSS),
  • it has Bootstrap theme out of the box,
  • it encourages SPA a lot and
  • it has a decent MVVM support, but you have to pay for it, I would rate Knockout.js much better than this.

I ended up building a decent excel based application on Heroku. As I proceeded to do complex things, I realized that in Java we end up with lot of boilerplate coding. I stumbled up on http://projectlombok.org/ to reduce some boilerplate, but still lot of boilerplate… this forced me to think if this is the reason people move towards modern programming languages like Scala, Groovy, and my latest favorite Clojure.

Clojure in particular is interesting because it is JVM based, follows Lisp way of working, you can write efficient code and avoid boilerplate, and has ClojureScript for web development. I did spend close to 1month exploring if it is good for web development.. the good thing is I learnt a new language. The big disadvantage is it has a huge learning curve, and it is not for weak hearted, you need to be good in emacs and some good frameworks like http://hoplon.io/ only work in UNIX platforms.

Javascript world:

In essence, I realized that if you want to be good web development person you cannot avoid Javascript, love it or hate it, embrace it. Again my journey started with understanding Ember.js. It is a good framework, but poor documentation and heavyweight. One of my friend pointed me to Knockout.js (it has a strong MVVM support), I loved it. I was also looking for a SPA, I stumbled upon, http://durandaljs.com/ , according to me this is the right direction for SPA.

If you want a good IDE for Javascript, NetBeans IDE is one of the best. I am spoilt by STS IDE, features like intellisense, code formatting, running the app from within the IDE are a must. Luckily NetBeans supports all of these and more, it is tightly integrated with Chrome browser and has a plugin within Chrome for running and debugging frontend (much better than firebugs etc..).

Finally for server side, there were 2 candidates I was exploring, Node.Js and Grails. Again I have this love / hate relationship with Javascript I am still not sold on Nodejs . I am settling with Grails because it has strong STS IDE support. I am trying to rewrite my “excel on the web” application, I deployed on Heroku with durandaljs, Knockoutjs on the client side and Grails/ Groovy on the serverside, with strong JSON contracts. I will share some of these learning

Conclusion:

As I mentioned earlier, embrace Javascript, there is lot of matured frameworks in JS (Ember.js, Angular.js, Backbone.js, Knockout.js are popular ones). If you have a good IDE you can actually be productive. Also on the server side there are alternatives to Java like Groovy, Node.js. My preference is Groovy because I come from Spring background and I love STS IDE.

Advertisements

Incorporating LDAP with Play 2.x (Scala) application

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I extend my earlier blog Incorporating Authorization into Play 2.x (Scala) application to integrate with LDAP instead of database.

Again there might be better ways to do this, but right now there is no clear documentation. A quick googling will display this Google group link and this link and this Github code. All of them were of little help to me. So I took the 1st step and put one of these. I have used Unboundid LDAP SDK‘s InMemoryDirectoryServer.

As a first step we need to add the below dependency in Build.scala,

"com.unboundid" % "unboundid-ldapsdk" % "2.3.1",

Next we implement an in memory LDAP helper class LdapUtil.scala as below,

  def start(): InMemoryDirectoryServer = {
    val config = new InMemoryDirectoryServerConfig("dc=org");
    val listenerConfig = new InMemoryListenerConfig("test", null, 12345, null, null, null);
    config.setListenerConfigs(listenerConfig);
    config.setSchema(null); // do not check (attribute) schema
    val server = new InMemoryDirectoryServer(config);
    server.startListening();
...
    server.add("dn: cn=user@test.com,dc=staticsecurity,dc=geomajas,dc=org", "objectClass: person", "locale: nl_BE",
      "sn: NormalUser", "givenName: Joe", "memberOf: cn=testgroup,dc=roles,dc=geomajas,dc=org", "userPassword: password");
    server.add("dn: cn=admin@test.com,dc=staticsecurity,dc=geomajas,dc=org", "objectClass: person", "locale: nl_BE",
      "sn: Administrator", "givenName: Cindy", "memberOf: cn=testgroup,dc=roles,dc=geomajas,dc=org", "userPassword: password");

    server
  }

  def authenticate(email: String, password: String): Option[Account] = {
    val server = start

    val conn = server.getConnection();
    val entry = conn.getEntry("cn=" + email + ",dc=staticsecurity,dc=geomajas,dc=org");

    val permission = entry.getAttributeValue("sn").toString
    val retPass = entry.getAttributeValue("userPassword")
    server.shutDown(true)

    if (retPass.equals(password)) {
      println("password valid")
      val account = new Account(email, password, permission)
      toOption(account)
    } else {
      None
    }
  }

  def findByEmail(email: String): Option[Account] = {
    val server = start
    val conn = server.getConnection();
    val entry = conn.getEntry("cn=" + email + ",dc=staticsecurity,dc=geomajas,dc=org");

    val permission = entry.getAttributeValue("sn").toString
    val retPass = entry.getAttributeValue("userPassword")
    server.shutDown(true)

    val account = new Account(email, retPass, permission)
    toOption(account)
  }

If you notice the normal user rights are email:= user@test.com, pwd:= password and admin rights are email:= admin@test.com, pwd:= password. As in my earlier blog, we need to customize the AuthConfig as below,

trait AuthConfigImpl extends AuthConfig {
  type Id = String
  type User = Account
  type Authority = String
  val idTag = classTag[Id]
...
  def resolveUser(email: Id) = LdapUtil.findByEmail(email)
...
  def authorize(user: User, authority: Authority) = (user.permission, authority) match {
    case ("Administrator", _) => true
    case ("NormalUser", "NormalUser") => true
    case _ => false
  }
}

Login form looks as below as in Application.scala,

  val loginForm = Form {
    mapping("email" -> email, "password" -> text)(LdapUtil.authenticate)(_.map(u => (u.email, "")))
      .verifying("Invalid email or password", result => result.isDefined)
  }

Finally the usage looks as below refer CoffeesControler.scala,

def create = StackAction(AuthorityKey -> "Administrator") { implicit request =>
    database withSession {
      Ok(html.coffees.createForm(form, supplierSelect))
    }
  }

I hope this blog helped.

Incorporating Authorization into Play 2.x (Scala) application

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I will demonstrate how to use play20-auth to adopt to coffee example.

As a first step for this example we need to add dependency in Build.scala as below,

    "jp.t2v" %% "play2.auth"      % "0.9",
    "jp.t2v" %% "play2.auth.test" % "0.9" % "test",

We need to define a Account.scala domain object with permissions as below,

object Account extends Table[Account]("ACCOUNT") {
  lazy val database = Database.forDataSource(DB.getDataSource())

  def id = column[Int]("ID")
  def email = column[String]("EMAIL")
  def password = column[String]("PASSWORD")
  def name = column[String]("NAME")
  def permission = column[Permission]("PERMISSION")
  // Every table needs a * projection with the same type as the table's type parameter
  def * = id ~ email ~ password ~ name ~ permission <> (Account.apply _, Account.unapply _)

In order for Account object to accept Permission.scala object as one of the column we need to implement MappedTypeMapper for the Permission as below,

  implicit val PermissionTimeMapper = MappedTypeMapper.base[Permission, String](
    d => Permission.stringValueOf(d),
    t => Permission.valueOf(t))

  def valueOf(value: String): Permission = value match {
    case "Administrator" => Administrator
    case "NormalUser" => NormalUser
    case _ => throw new IllegalArgumentException()
  }

  def stringValueOf(value: Permission): String = value match {
    case Administrator => "Administrator"
    case NormalUser => "NormalUser"
    case _ => throw new IllegalArgumentException()
  }

Next step is, we need to implement a trait AuthConfigImpl extending AuthConfig in Application.scala indicating what is the User class to authenticate, what is the column that contains the Permission information and what is the redirecting page as below,

trait AuthConfigImpl extends AuthConfig {

  type Id = Int

  type User = Account

  type Authority = Permission

  val idTag = classTag[Id]

  val sessionTimeoutInSeconds = 3600

  def resolveUser(id: Id) = Account.findById(id)

  def loginSucceeded(request: RequestHeader) = Redirect(routes.CoffeesController.index)

  def logoutSucceeded(request: RequestHeader) = Redirect(routes.Application.login)

  def authenticationFailed(request: RequestHeader) = Redirect(routes.Application.login)

  def authorizationFailed(request: RequestHeader) = Forbidden("no permission")

  def authorize(user: User, authority: Authority) = (user.permission, authority) match {
    case (Administrator, _) => true
    case (NormalUser, NormalUser) => true
    case _ => false
  }
}

Now we need to submit the loginForm to authenticate a user in Application.scala as below,

  val loginForm = Form {
    mapping("email" -> email, "password" -> text)(Account.authenticate)(_.map(u => (u.email, "")))
      .verifying("Invalid email or password", result => result.isDefined)
  }

Account.scala authenticate method looks as below,

  def authenticate(email: String, password: String): Option[Account] = {
    findByEmail(email).filter { account => password.equals(account.password) }
  }

For details about integration with the action in the controller refer CoffeesController.scala as below,

object CoffeesController extends Controller with AuthElement with AuthConfigImpl {
  def delete(pk: String) = StackAction(AuthorityKey -> Administrator) { implicit request =>
    database withSession {
      Home.flashing(Coffees.findByPK(pk).delete match {
        case 0 => "failure" -> "Entity has Not been deleted"
        case x => "success" -> s"Entity has been deleted (deleted $x row(s))"
      })
    }
  }
}

Notice how we use StackAction and validate for Administrator permission in the controller.

I hope this blog helped you.

Play 2.x (Scala) is it a Spring MVC contender? – Introduction

For people in hurry here is the code and the steps.

I have been playing with Scala and Play 2.x for past 6 months and have gained lot of knowledge. I have been working with Spring related technologies for past 8 yrs. In the next few blogs I will be really exploring if the Scala flavor of Play 2.x is ready for prime time.

As usual, I will be exploring how well we can build Data Access Layer, Controller, Frontend integration with Play 2.x using Test Driven Development. I will also be exploring how well Play 2.x is integrated with Security (Authentication/Authorization) capabilities and how well Scala is integrated with other Authentication systems like LDAP.

The use case I will be talking in the next few blogs is the popular Coffee Supplier web application, which demonstrates a simple CRUD base application. And I will elaborate aspects only Admin users can create the Coffee and Normal users can see the list.

One common thing about Play 2.x and Spring MVC is both follow MVC design patterns. There are also other Scala Web frameworks like Lift, I haven’t played with it yet.

Overall architecture of Play 2.1 MVC is as below

Play 2.1 over all architecture

Play 2.1 over all architecture

In this example, I will use popular tools like Slick to access the Database, Play-Auth to do authentication and authorization. And I will extensively use ScalaTest to do Test Driven Development( TDD)/ Behavior Driven Development( BDD).

The layers I will be developing in TDD in the order are,

Incorporating Login/ Authentication into Play 2.x (Scala) application

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I will demonstrate how to extend Security.Authenticated standard Play API to implement basic authentication in your application.

I took this code play-test-security as my basis for implementing Security.Authenticated based authentication.

As a first step, I will extend this class to implement a Security trait as below,

trait Secured {
  self: Controller =>

  /**
   * Retrieve the connected user id.
   */
  def username(request: RequestHeader) = request.session.get("email")

  /**
   * Redirect to login if the use in not authorized.
   */
  def onUnauthorized(request: RequestHeader): Result

  def IsAuthenticated(f: => String => Request[AnyContent] => Result) =
    Security.Authenticated(username, onUnauthorized) { user =>
      Action(request => f(user)(request))
    }
}

As provided in the comment section it is clear what each method does. Next step is to plumb the login steps refer Application.scala as below,

  lazy val loginForm = Form(
    tuple(
      "email" -> text,
      "password" -> text) verifying ("Invalid user or password", result => result match {
        case (email, password) => {
          println("user=" + email + " password=" + password);
          val userList = Users.authenticate(email, password)
          userList == 1
        }
        case _ => false
      }))

  def login = Action { implicit request =>
    Ok(html.login(loginForm))
  }

  /**
   * Handle login form submission.
   */
  def authenticate = Action { implicit request =>
    loginForm.bindFromRequest.fold(
      formWithErrors => BadRequest(html.login(formWithErrors)),
      user => Redirect(routes.CoffeesController.index).withSession("email" -> user._1))
  }

  /**
   * Logout and clean the session.
   */
  def logout = Action {
    Redirect(routes.Application.login).withNewSession.flashing(
      "success" -> "You've been logged out")
  }

The User Slick domain object and the authenticate method in User.scala looks as below,

object Users extends Table[User]("USER") {
  lazy val database = Database.forDataSource(DB.getDataSource())

  // -- Parsers

  def email = column[String]("EMAIL", O.PrimaryKey)
  def name = column[String]("NAME")
  def password = column[String]("PASSWORD")

  def * = email ~ name ~ password <> (User.apply _, User.unapply _)
//....
  def authenticate(email: String, password: String): Int = {
    database withSession { implicit session =>
      val q1 = for (u       println("^^^^^^^^" + Query(q1.length).first)
      Query(q1.length).first
    }
  }

Finally the CoffeesController.scala where we need to override onUnauthorized method and put the IsAuthenticated block in each action as below,

  def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login())

  /**
   * Display the paginated list.
   *
   * @param page Current page number (starts from 0)
   * @param orderBy Column to be sorted
   * @param filter Filter applied on entity names
   */
  def list(page: Int, orderBy: Int, filter: String = "%") = IsAuthenticated { username =>
    implicit request =>
      database withSession {
        Ok(html.coffees.list(
          Page(Coffees.list(page, pageSize, orderBy, filter).list,
            page,
            offset = pageSize * page,
            Coffees.findAll(filter).list.size),
          orderBy,
          filter))
      }
  }

To test if authentication worked, start play,

play run

And when you type the url http://localhost:9000/coffee, you get the login page as below,

Scala Secured.Authenticated-login

Scala Secured.Authenticated-login

I hope this blog helped you. In my next blog, I will show how you do authorization.

Testing Frontend integration with Play 2.x (Scala)

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I will demonstrate how we implement a simple test to test the Web layer using TestServer. I will continue from my earlier example of Implementing Controller using Play 2.x (Scala), ScalaMock where I did the mock testing.

Refer Build.scala for build configuration.

In this blog, I will be testing the routes refer CoffeesControllerTest.scala for more details, the snippet is as below,

    it("POST /coffees/Colombian/delete should return SEE_OTHER") {
      running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {

        val Some(result) = route(FakeRequest(POST, "/coffees/Colombian/delete"))
        status(result) should equal(SEE_OTHER)
      }
    }

    it("POST wrong url /coffees/Colombian/delete1 should return None") {
      running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {

        val result = route(FakeRequest(POST, "/coffees/Colombian/delete1"))
        result should equal(None)
      }
    }

In the next block I will show how to do end to end testing from web layer using TestServer refer IntegrationTest.scala ,

class IntegrationSpec extends Specification {

  "Application" should {

    "work from within a browser" in {
      running(TestServer(3333), HTMLUNIT) { browser =>

        browser.goTo("http://localhost:3333/coffees")
        browser.pageSource must contain("Colombian")
      }
    }

    "work from within a browser" in {
      running(TestServer(3333), HTMLUNIT) { browser =>

        browser.goTo("http://localhost:3333/coffees")

        browser.pageSource must contain("Colombian")
      }
    }

    "work from within a browser" in {
      running(TestServer(3333), HTMLUNIT) { browser =>

        browser.goTo("http://localhost:3333/coffees")
        browser.pageSource must not contain("Colombian1")
      }
    }

  }
}

Also while testing the application from web layer, we need to populate the data in the Global.scala as below,

object Global extends GlobalSettings {

  override def onStart(app: Application) {

    lazy val database = Database.forDataSource(DB.getDataSource())

    database withSession {
      // Create the tables, including primary and foreign keys
      val ddl = (Suppliers.ddl ++ Coffees.ddl)

      ddl.create

      // Insert some suppliers
      Suppliers.insertAll(
        Supplier(Some(101), "Acme, Inc.", "99 Market Street", "Groundsville", "CA", "95199"),
//...
      // Insert some coffees (using JDBC's batch insert feature, if supported by the DB)
      Coffees.insertAll(
        Coffee(Some("Colombian"), 101, 799, 0, 0),
    }
  }
}

I hope this blog helped you. In the next blog I will implement simple authentication.