views:

619

answers:

2

I'm writing a small webapp in Grails, and to make sure all users are authenticated I'm using the following filter:

class LoginFilters {
  static filters = {
    loginCheck(controller:'*', action:'*') {
      before = {
        if (session.user_id) {
          request.user = User.get(session.user_id)
        } else if (!actionName.equals("login")) {
          redirect(controller: "login", action: "login")
          return false
        }
      }
    }
  }
}

And all controller methods start with reading the user property of the request object:

def actionName = {
   def user = request.user
   ...
}

The code above works, but I'd rather avoid the duplicate code in the all controller methods. Would it be possible for the filter to bind the user object to a variable named "user" instead of "request.user", that will be accessible from all controllers?

I understand that there might be scoping issues that makes this impossible, but the Grails framework seems to be able to create quite some magic under the hood, so I figured it might be worth asking.

+1  A: 

Using the beforeInterceptor in a controller may help:

class LoginController {

    def user

    def beforeInterceptor = {
     user = request.user
    }

    def index = { 
     render text:"index: ${user}"     
    }

    def test = {
     render text:"test: ${user}"       
    }
}
chanwit
A: 

I think you can do this but is it really worth the trouble? It seems to me your only advantage is typing "user" instead of "request.user". Not a big gain. Anyway, I think you could follow the instructions in "12.7 Adding Dynamic Methods at Runtime" of the User Guide. I think that if you created a dynamic method "getUser() {return request.user}" that the Groovy JavaBeans getter/setter access would allow you to simply reference "user" the way you want.

If you do add a dynamic method you might want to skip the filter and do it all in the dynamic method.