Friday, February 29, 2008

Gotcha: Grails Auto Recompile Doesn't Do GSP

Grails does the auto recompile thing, much like Turbogears etc., but it doesn't seem to work for gsp pages, in particular, main.gsp. Which can trip you up, if you're trying to make a couple simple changes to your first Grails app.

Wednesday, February 27, 2008

Gotcha: Grails Capitalization

So, apparently Grails doesn't like Controllers starting with multiple capitol letters (i.e. TLAcronym). If you create a domain class with all lowercase, it will capitalize it for you, but if you try to create TLAcronym, it happily plays along. Then if you generate-all or do scaffolding for that domain class, you won't be able to access your controller. I've raised an issue for this here: GRAILS-2541.

Thursday, February 14, 2008

Acegi on Grails Tutorial

So, neither the information on the Plugin Page for the Acegi Security Plugin, nor the info in the acegi tutorial actually work completely. Here's a real tutorial for doing this. (Step 6 is where the existing documentation fails)

Step 1. Install Grails

Step 2. Download the Acegi Security Plugin. (I downloaded version 0.2 it as a zip file, to %GRAILS_HOME%/plugins/)

Step 3. Create a new Grails Project, and cd into the new project folder:

grails create-app SecurityTutorial
cd SecurityTutorial

Step 4. Add the Acegi Security Plugin. Note that you can install plugins by name using some lookup service, but the Acegi plugin won't be found.

grails install-plugin %GRAILS_HOME%/plugins/grails-acegi-0.2.zip

Step 5. Installing the Acegi Plugin will add some new scripts to your project:

  • create-auth-domains [PersonDomainName] [AuthorityDomainName: this creates the domain model needed by the plugin, Person, Authority, and RequestMap classes, login and logout controllers, as well as the login view. You can give optional names as arguments to replace Person and Authority.
  • generate-manager: creates the scaffolding controllers to add new Person, Authority, and RequestMap object in your database
  • generate-registration: create a register and captcha controller, as well as matching views, and an emailer service.

Run each of these commands.

grails create-auth-domains
grails generate-mapper
grails generate-registration

Step 6. Setup BootStrap.groovy to contain some sample data, as follows:

// ProjectFolder/grails-app/conf/Bootstrap.groovyclass BootStrap {

def init = { servletContext ->

// get a AcegiSecurity AuthenticateService
def authenticateService = new AuthenticateService()
// use it to create an encoded password
def md5pass = authenticateService.passwordEncoder("pass")

// Create two sample users
// NB: you must specify all the Person attributes, otherwise
// Grails will fail quietly to add these to the database
def user_root = new Person(username:"root",
userRealName:"Root User",
passwd:md5pass,
enabled:true,
email:"root@example.com",
email_show:true,
description:"Desc").save()
def user_admin = new Person(username:"admin",
userRealName:"Admin User",
passwd:md5pass,
enabled:true,
email:"admin@example.com",
email_show:false,
description:"Desc").save()

// Add some sample Roles, add the users to those roles
def role_superuser = new Authority(description:"Superuser",
authority:"ROLE_SUPERUSER")
role_superuser.addToPeople(user_root)
role_superuser.save()

// See AcegiConfig.groovy, at the bottom, there's a defaultrole
// setting, you must make one to allow registration to work.
def role_user = new Authority(description:"User Role",
authority:"ROLE_USER")
role_user.addToPeople(user_admin)
role_user.addToPeople(user_root)
role_user.save()

// Create some Request Maps
new Requestmap(url:"/captcha/**",
configAttribute:"ROLE_SUPERUSER").save()
new Requestmap(url:"/register/**",
configAttribute:"ROLE_USER").save()

}
def destroy = {
}
}

We also have to edit the RegisterController.groovy to fix a bug.

// ProjectFolder/grails-app/controllers/RegisterController.groovy                    // Line # 159-161
person.save(flush:true)
def parMap =['j_username':person.username,'j_password':params.passwd]
// change this line:
// redirect(controller:'login',action:'../j_acegi_security_check',params:parMap)
// to this:
redirect(controller:'login',action:"auth")

Step 7. Run the application

grails run-app

Step 8. Play around. Notice that you when you try to go to the register controller, it asks for a login, then, since you're already logged in, the register controller just shows you your info with a redirect(action "show"). Go delete the RequestMap for the register url, make sure you logout, then try again. See how the captcha is broken? Go remove the captcha RequestMap, and try again.

Thankyou Markmail

So, I've been trying to dig through codehaus's mail archives for the Groovy Lists. Oh wow, what a terrible interface, and miserable search. A lucky Google search later, and I stumble on Markmail's Groovy Site. Not only do I find the mail thread I was hoping for which solved my problem, but a fantastic interface to some of the larger tech mailing lists that has a fantastic interface and great search. The date restraints and graphs are nice, but even nicer: Awesome, awesome thread display, really nice interface for checking out attachments, perma-links, and powerful search features. Good job guys, I saved enough time to write this :)