Archive for January, 2009

links for 2009-01-25

Sunday, January 25th, 2009

links for 2009-01-13

Tuesday, January 13th, 2009

Grails Acegi (Spring Security) Plugin v0.5 Released

Monday, January 12th, 2009

Version 0.5 went out yesterday. This was an interesting one to work on. There were a few relatively minor bug fixes, but there are four new features/enhancements and the plugin now works with Grails 1.1.

Probably the coolest new feature is being able to define security rules directly in the Controllers. Previously there were two ways to define the URL->Role mappings, in a static string (the standard Spring Security approach) or using Requestmap entries in the database. Now there’s a third – using annotations in controllers.

I’d written about using annotations previously and I used that approach. Annotations can be ugly, but I think here they’re great here since they’ll only ever have a fairly short list of values (roles plus special tokens like IS_AUTHENTICATED_FULLY, etc.). You can annotate individual actions and/or put an annotation at the class level and then all of the actions in the controller share those mappings, and if needed you can override that for individual actions. And they’re inheritable, so if you use controller base classes you can define them there and share rules throughout the hierarchy. For example, if you have an AbstractAdminController that all administrative controllers extend you could annotate just the base class with @Secured(['ROLE_ADMIN']) and restrict access to the entire admin hierarchy.

There are some notes here describing the new approach and the original two.

To better support stuff like administrative sections of a site, I added in an IP address filter so you can specify IP ranges (using Ant patterns or masks) for URLs. This way you can restrict access for your admin area to ’10.**’ or ‘192.168.**’ in addition to requiring specific roles to ensure that only users in the intranet or VPN have access.

I also added in support for ChannelProcessingFilter to allow defining which URLs require HTTPS and which require HTTP. With this addition there aren’t many Spring Security filters left that haven’t been mapped in the plugin – just ConcurrentSessionFilter, SessionFixationProtectionFilter, X509PreAuthenticatedProcessingFilter, and RequestHeaderPreAuthenticatedProcessingFilter.

Someone on the Grails user mailing list was talking about Facebook logins, and I’d been wanting an excuse to play with their API so I wired up support for that. It’s of limited use (like the OpenID support) since you don’t get much information from the authentication, so there would be a lot of manual work required in the app when setting up user information in the database. For example, you don’t even get the login name/email, only the numeric ID, so that has to be the username attribute in the User table.

Getting things going with Grails 1.1 was interesting. There was one real bug that I’d introduced in AuthenticatedVetoableDecisionManager – I think it’s a Groovy bug but I worked around it. I had named both a variable and a method deny, and it was trying to invoke deny() on the variable instead of the method. I changed it to denyCount which is more self-documenting and it was fine.

The plugin generates its own controllers and CRUD pages, so I needed to update those to use new 1.1 features. The allowedMethods map is now static so I changed those to avoid warnings at startup. Optimistic locking is now checked in controllers by adding an <input type='hidden'> form element in the GSP with the current domain instance version and checking it against the database after submitting updates, so I wired that up so the User/Role/Requestmap management pages work like non-plugin pages.

I also had to rework my automated testing due to the changes in the way plugins are installed in 1.1. I have an Ant task that creates a test project, installs the plugin, and configures the app for testing. Then I run a suite of automated tests using the WebTest plugin. Plugins are now global by default, so installing a plugin for a second app will share the plugin that the first app installed, which will save a bunch of space both locally and in source control. But I need the plugin to be local to the test app, and this is possible by overriding the default behavior and reverting to the 1.0 approach by setting grails.plugins.dir='plugins' in grails-app/conf/BuildConfig.groovy. And this doesn’t affect 1.0 since BuildConfig.groovy is ignored.

So check out the new release. There are no backwards compatibility issues, so upgrading is simple. Check out the fixes and enhancements here and the docs here.

Spring Bean Aliases in Grails

Tuesday, January 06th, 2009

I was looking at the source code of a Spring application recently and saw an applicationContext.xml element that I hadn’t seen before: <alias>. It turns out this has been around for quite a while, since v1.2 (2005). It sure would have been convenient several months ago.

My first Grails app was a Live Chat app for tech support. I used Comet, so I needed to access Grails beans from Java classes. I did this by having my Services implement an interface, and used that as the type for the Spring bean dependency injection.

But the problem with that was that in Grails you don’t get to choose the bean names of artifacts – there’s a strict convention, so a Service named ChatService is registered as chatService. But the convention I’ve always used is to name my interface ChatService and name the implementation class ChatServiceImpl. But then the Spring bean name would be chatServiceImpl.

In a regular Spring app I’d implicitly alias when I added the bean element to the applicationContext.xml file, e.g.

<bean id='chatService' class='' />

So instead I chose an option that I really dislike – I named the interface IChatService and the Grails Service ChatService.

But with the <alias> tag, I should be able to do what I want – name the interface ChatService and the Grails Service ChatServiceImpl, and add

<alias name='chatServiceImpl' alias='chatService' />

to resources.xml. The original bean name will still be there, but I can use the more natural bean name for dependency injection.

This doesn’t cause an error, but it doesn’t work either. I spent some time in a debugger and the alias is registered, but the application context that’s available when the app is running is different from the one that the alias was added to.

But it turns out that you can add programatically add aliases at any time, so I added the alias call to BootStrap.groovy:

class BootStrap {

  def grailsApplication

  def init = { servletContext ->
    grailsApplication.mainContext.registerAlias('chatServiceImpl', 'chatService')

  def destroy = {}

and now I can use the chatService alias as the bean name.

I noticed though that since aliases are stored in a Map and not directly in the bean registry, that ctx.getBeanDefinitionNames() only returns ‘real’ bean names and no aliases. But it turns out that it’s pretty simple to get all bean names and aliases:

def allNames = [] as Set
ctx.beanDefinitionNames.each { name ->
    allNames << name
    ctx.getAliases(name).each { alias -> allNames << alias }

A Grails Plugin for Twitter

Monday, January 05th, 2009

I’ve recently started using Twitter, late to the party as usual 🙂 So when somebody asked a question this weekend on the Grails User mailing list about using the JTwitter API, I took a look at it and being the easily-distracted person that I am, started playing with it.1

This seemed like something that people might want to have available as a plugin, so I created a simple implementation, basically just a Service to wrap the JTwitter API and a TagLib to help with rendering, plus a sample Controller and GSPs.

Check out the plugin’s wiki page for installation instructions, usage, etc. If you find this useful and discover bugs or want to suggest new features, send an email to the Grails User mailing list or create an issue in JIRA.

  1. Actually I have the attention span of a gnat – someone else asked this weekend about integrating Facebook logins with a Grails app so I spent a few hours adding that to the Acegi (Spring Security) plugin[back]

An internal error occurred while showing an internal error

Friday, January 02nd, 2009

I get this a lot using the Groovy/Grails Eclipse plugin at work:

An internal error occurred while showing an internal error

This reminds me of that line from Brazil – “My complications had complications.”

Yes I’ve tried Netbeans and IntelliJ – they’re nice but I don’t want to re-learn an IDE, I’ve spent a lot of time with Eclipse and other than the Groovy plugin, it does what I need and very well. And yes I’ve played with memory settings in eclipse.ini.

I have several Grails apps in my workspace, so I try to keep open only the ones that I’m actively using to avoid memory issues. But eventually memory gets screwy, and I get to restart Eclipse again. Yay!

I’m definitely looking forward to SpringSource allocating resources to improving the plugin now that they’ve aquired G2One – should help tremendously.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.