Login application - Validate from Database

Posted by Anantha Narayanan On 5:17 PM


Click here to see a very basic login application with hard-coded user credentials. In current article I am discussing as on how to validate from a table where login id and password is stored. The article above points to the usage of flash and session's uses. I will not discuss more about flash and session in this article.

My assumption is that a person is assigned for a login with his email id. Based on that I planned for a domain called "Person" as below (I named the application happy):

package happy
class Person {
  String firstName
  String lastName
  String emailID
  String loginPassword
  Boolean superUser

  static constraints = { 
    firstName(size:1..120,nullable:false,blank:false)
    lastName(size:1..120,nullable:false,blank:false)
    emailID(email:true,size:1..120,nullable:false,blank:false)
    loginPassword(password:true,size:6..20,nullable:false,blank:false)
  }
}


In my PersonController.groovy, I added an interceptor which should validate a session. If no session is available it should redirect me to login page.


package happy
class PersonController {
  def beforeInterceptor = [action.this.&checkUser]
  static scaffold = true
  def checkUser() {
    if(!session.user) {
      redirect(controller:'person',action:'login')
      flash.message = "Invalid Username/Password, please try again."
    }
  }
}


I have successfully added a validation for all controllers in Person. If there is no login detected the user should be redirected to a login page. Next part is to design that page.


  def login = {
  }
 
   

I have put a blank controller inside the Person controller for login. Now I have to create a gsp file for this controller to successfully work. For this, I copied the index.gsp from views folder and copied it as login.gsp inside person foler within views. I deleted the entire contents within body tag and replaced with the following code:


<body>
  <a href="#page-body" class="skip">
  <g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
  <g:render template="loginHeader"/>
  <div class="bodyContent" id="bodyContent">
    <g:if test="${flash.message}">
      <div class="message">${flash.message}
</div>
    </g:if>
  </div>
</body>


It is a simple code, please read through all lines. From <g:render> tag, I will explain. It is looking for a _loginHeader.gsp as its a template. It then displays the body content and if any messages.

The following are the contents of _loginHeader.gsp located in views/person folder.


<g:if test="${session.user}">
<div class="login">
<g:remoteLink controller="person" action="list" update="bodyContent">${session.user.emailID}</g:remoteLink> | <g:link action="logout">Logout</g:link>
</div>
</g:if>
<g:else>
<g:form action="doLogin" method="post">
<div class="login">
 <label for='emailID'>Email ID</label>
 <input id="emailID" required type='text' name='emailID' value='${person?.emailID}' />
 <label for='loginPassword'>Password</label>
 <input id="loginPassword" required type='password' name='loginPassword' value='${person?.loginPassword}' />
 <input type="submit" value="Login"></input>
 </div>
</g:form>
</g:else>


This page will be used across all pages, that is why I decided to create it as a template. It checks for a session, and if found it displays the person logged in or else displays the login input boxes.

The form which has the input boxes for email ID and password are submitting to a doLogin. This method must be defined within the PersonController.groovy as well.

def doLogin = {
  def user = Person.findWhere(emailID:params['emailID'],loginPassword:params['loginPassword'])
  session.user = user
  if (user){
    redirect(controller:'person',action:'list')
    flash.message = "Logged in as <b>$user.firstName $user.lastName ($user.emailID)</b>"
  }else{
    redirect(controller:'person',action:'login')
    flash.message = "Invalid Username/Password, please try again."
  }
}

This method extracts values from params variable which will have all input boxes value. By checking using Person.findWhere by passing these parameters (Email ID &amp; Login Password) we will get some value to user object. If user variable was null then we assume that it is an invalid login and once more redirect to login page. If the validation was successfull, this will redirect to Person/List page.

Download Application Note: The application uses Grails 2

Bug Tracker Application - biTracker

Posted by Anantha Narayanan On 3:52 PM

This application can be used to track issues/bugs which might be arising in development.

The features include:
  • User defined resource names 
  • User defined browser names (in case of browser based application for checking compatibility) 
  • User defined pages/program units 
  • User defined environments (like uat/development etc) 
  • User defined severity status 
  • Issues/bugs are searchable using searchable plugin 

This application is intented to be a starting place wherein MS-Excel sheets can be replaced and the bugs/issues could be saved to Oracle database.

The configuration for connecting to oracle can be done by modifying the file DataSource.groovy inside grails-app/conf folder. 

Download the source and execute this application and serve your clients much better.

Request your help in improving this and making it a full-fledged application. Please share your valuable comments below.

What is SCAFFOLD?

Posted by Anantha Narayanan On 10:48 PM

Scaffold in normal English means

"scaf·fold·ing/ˈskafəldiNG/Noun:
  1. A temporary structure on the outside of a building, made of wooden planks and metal poles, used by workers while building, repairing, or...
  2. The materials used in such a structure."

In Grails and some more "Model-View-Controller (MVC for short)" frameworks this term is used to describe the automatic "Create-Read-Update-Delete" database functions that are constructed and executed at run time.

For example if you have defined a domain class in Grails, the table can be created by the framework. More, Grails also allows you to have web interface for the domain automatically for the said operations on your table:
  • CREATE (INSERT)
  • READ (QUERY)
  • UPDATE
  • DELETE
These above operations are termed as scaffolding or CRUD in Grails.

A real use of a SCAFFOLD is in prototyping your design, wherein most of these code does not make much importance to you. Once the design is frozen you may move to more secure and customized way of CRUD operations.

Automatic Scaffold Controller

Posted by Anantha Narayanan On 10:39 PM

By default if you are creating a controller using the following command:

grails create-controller org.example.DomainClass

Suppose your controller is based on an existing DomainClass, you might want to jump start using scaffolding.

You might be opening the controller file and commenting the code which Grails has created for you.

class DomainClassController {

  def index = { }

}
You might be adding the magic keyword that allows scaffolding later.

class DomainClassController {

  //def index = { }

  def scaffold = true

}
If you have many number of controllers to be created for prototyping and want to avoid this commenting and copy/paste activities use the following command:

grails create-scaffold-controller org.example.DomainClass

Grails will generate the controller with scaffold magic keyword by default.

Hope you like this tip (if you are a beginner of Grails and if you are cursing with prototyping for numerous controllers).

Welcome Grails 2

Posted by Anantha Narayanan On 1:01 AM

It was only recently that Grails 2 was released. Being using an ubuntu Linux distro, it is very easy to upgrade Grails and I did.

The first thing I tried was to execute an already existing application (using Grails 1.3.7) and it gave me an error:

| NOTE: Your application currently expects grails version [1.3.7], this target will upgrade it to Grails 2.0.0

I issued the command grails upgrade

WARNING: This target will upgrade an older Grails application to 2.0.0.
  Are you sure you want to continue? [y,n]

I gave a proceed signal and Grails upgraded my application after downloading necessary files. Pretty impressive.
When I executed the application using run-app I got the following error:
| Error 2011-12-20 00:35:57,627 [Thread-7] ERROR context.GrailsContextLoader - Error executing bootstraps: Database driver [org.hsqldb.jdbcDriver] for HSQLDB not found. Since Grails 2.0 H2 is now the default database. You need to either add the 'org.h2.Driver' class as your database driver and change the connect URL format (for example 'jdbc:h2:mem:devDb') in DataSource.groovy or add HSQLDB as a dependency of your application.

He he, looking complex. Do not worry. There is one change that Grails 2 is shipped with. Grails 1.3.7 was using HSQLDB and Grails 2 uses H2 database. The reference to HSQLDB made Grails to spit this error message.

But Grails also has pointed out as to how to solve it.
  1. Modify the org.hsqldb.jdbcDriver with org.h2.Driver in driverClassName.
  2. Modify url = "jdbc:hsqldb:mem:devDB" with url = "jdbc:h2:mem:devDb"
That's it. I was able to execute the application, though I did not appreciate any interface facelift with my old application. Now I created a new application and created a domain class and a controller for it.

When executed the HTML5 styling was what I was expecting. Yes and I got it. So this is another change in Grails 2.

For more about Grails 2, check here.

If you like my blog, please leave your valuable suggestions below.

Difference between nullable and blank

Posted by Anantha Narayanan On 12:10 AM

What is the difference between nullable and blank constraints in Grails domain class? 

Consider the following constraint defined within a domain class:
Package nulltest

Class Test1{
 String someValue
 static constraints = {
   someValue blank:true
 }
}
Grails while compling and running the application creates the fiels someValue to allow blank value.

You will get the following error if you have a controller action for this domain:
Property [someValue] of class [class nulltest.Test1] cannot be null

This property blank is only applicable for a String field. The reason, the term blank does not sound good for non-string fields. To achieve the same for a non-string field, use nullable constraint here.

Package nulltest

Class Test1{
 BigDecimal someValue
 static constraints = {
   someValue nullable:true
 }
}
Note: By default, all domain class properties have an implicit nullable:false constraint.

Recommended Post Slide Out For Blogger