Interceptor usecase

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Interceptor usecase

Yasu
Hello list,
  The interceptor introduced recently looks very cool.  I like that I
can play with AOP idea
with ease of Groovy language.

  As the documentation suggests, one of the typical use of the
interceptor is for authentication.  The logical place to put the
authentication interceptor logic would be
something like LoginController controller class.  However, if I make a
closure like

--- in LoginController.groovy ---
    @Property Closure authCheck = {
           if(session['user'] == null){
                 // reject the request and redirect to login page
           }
    }

in the LoginContrller and in, say, UserController I use the closure as

--- in UserController.groovy --
    def LoginController  lc = new LoginController()
    @Property beforeInterceptor = lc.authCheck

The interceptor will fail because the 'session' object is injected into
the UserController but not
into the LoginController.  I think this is a reasonable thing to do
since I do not want to
duplicate the authCheck code in every controller that might need
authentication check.

I think it would be nice if I can write interceptor closure like

    @Property Closure authCheck = {
           // notice 'it'
           if(it.session['user'] == null){
                 // reject the request and redirect to login page
           }
    }

and assume that 'it' will be referencing the currently executing
controller.
This way, I can use the same closure in all the controllers.

Right now,  I can share the above authCheck closure by having a function
that returns curried closure or using lexical scope like

--- in LoginController.groovy ---
def getAuthCheckClosure(controller){
   return this.authCheck.curry(controller)
}

--- in UserController.groovy --
def LoginController lc = new LoginController()
@Property beforeInterceptor = this.lc.getAuthCheckClosure(this)

Or maybe a static function that does the same thing, but either way,
it does not look very groovy...

Again I have only less than a week of experience with groovy+grails so I
may be missing something.

Any insights?


Reply | Threaded
Open this post in threaded view
|

Re: Interceptor usecase

graemer
On 3/24/06, Yasuhiko Sakakibara <[hidden email]> wrote:

> Hello list,
>   The interceptor introduced recently looks very cool.  I like that I
> can play with AOP idea
> with ease of Groovy language.
>
>   As the documentation suggests, one of the typical use of the
> interceptor is for authentication.  The logical place to put the
> authentication interceptor logic would be
> something like LoginController controller class.  However, if I make a
> closure like
>
> --- in LoginController.groovy ---
>     @Property Closure authCheck = {
>            if(session['user'] == null){
>                  // reject the request and redirect to login page
>            }
>     }
>
> in the LoginContrller and in, say, UserController I use the closure as
>
> --- in UserController.groovy --
>     def LoginController  lc = new LoginController()
>     @Property beforeInterceptor = lc.authCheck
>
> The interceptor will fail because the 'session' object is injected into
> the UserController but not
> into the LoginController.  I think this is a reasonable thing to do
> since I do not want to
> duplicate the authCheck code in every controller that might need
> authentication check.

A better pattern it to put your authentication into a base class
controller and then change UserController to extend this base class.

>
> I think it would be nice if I can write interceptor closure like
>
>     @Property Closure authCheck = {
>            // notice 'it'
>            if(it.session['user'] == null){
>                  // reject the request and redirect to login page
>            }
>     }
>
> and assume that 'it' will be referencing the currently executing
> controller.
> This way, I can use the same closure in all the controllers.
You can by subclassing

Cheers
Graeme

>
> Right now,  I can share the above authCheck closure by having a function
> that returns curried closure or using lexical scope like
>
> --- in LoginController.groovy ---
> def getAuthCheckClosure(controller){
>    return this.authCheck.curry(controller)
> }
>
> --- in UserController.groovy --
> def LoginController lc = new LoginController()
> @Property beforeInterceptor = this.lc.getAuthCheckClosure(this)
>
> Or maybe a static function that does the same thing, but either way,
> it does not look very groovy...
>
> Again I have only less than a week of experience with groovy+grails so I
> may be missing something.
>
> Any insights?
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Interceptor usecase

Yasu
Graeme Rocher wrote:

>On 3/24/06, Yasuhiko Sakakibara <[hidden email]> wrote:
>  
>
>>Hello list,
>>  The interceptor introduced recently looks very cool.  I like that I
>>can play with AOP idea
>>with ease of Groovy language.
>>
>>  As the documentation suggests, one of the typical use of the
>>interceptor is for authentication.  The logical place to put the
>>authentication interceptor logic would be
>>something like LoginController controller class.  However, if I make a
>>closure like
>>
>>--- in LoginController.groovy ---
>>    @Property Closure authCheck = {
>>           if(session['user'] == null){
>>                 // reject the request and redirect to login page
>>           }
>>    }
>>
>>in the LoginContrller and in, say, UserController I use the closure as
>>
>>--- in UserController.groovy --
>>    def LoginController  lc = new LoginController()
>>    @Property beforeInterceptor = lc.authCheck
>>
>>The interceptor will fail because the 'session' object is injected into
>>the UserController but not
>>into the LoginController.  I think this is a reasonable thing to do
>>since I do not want to
>>duplicate the authCheck code in every controller that might need
>>authentication check.
>>    
>>
>
>A better pattern it to put your authentication into a base class
>controller and then change UserController to extend this base class.
>
>  
>
I am not sure about the suggested solution.  Implementaion inheritance
is, in my view, best avoided.

Let's say, that  I want to share afterInterceptor as well.  Now, my base
class would
have both beforeInterceptor and afterInterceptor methods/closure
implemented.  What would happen if, for some reason, I wanted to have
different authentication mechanism for some Controllers?
I will need to create another class inheriting the base class and have
different beforeInterceptor method.  Then, after some time, I would need
to implement different afterInterceptor, completely orthogonal to the
beforeInterceptor change, for some of my controllers.
I will end up having four base classes with duplicate codes.

>>I think it would be nice if I can write interceptor closure like
>>
>>    @Property Closure authCheck = {
>>           // notice 'it'
>>           if(it.session['user'] == null){
>>                 // reject the request and redirect to login page
>>           }
>>    }
>>
>>and assume that 'it' will be referencing the currently executing
>>controller.
>>This way, I can use the same closure in all the controllers.
>>    
>>
>You can by subclassing
>
>Cheers
>Graeme
>  
>
>>Right now,  I can share the above authCheck closure by having a function
>>that returns curried closure or using lexical scope like
>>
>>--- in LoginController.groovy ---
>>def getAuthCheckClosure(controller){
>>   return this.authCheck.curry(controller)
>>}
>>
>>--- in UserController.groovy --
>>def LoginController lc = new LoginController()
>>@Property beforeInterceptor = this.lc.getAuthCheckClosure(this)
>>
>>Or maybe a static function that does the same thing, but either way,
>>it does not look very groovy...
>>
>>Again I have only less than a week of experience with groovy+grails so I
>>may be missing something.
>>
>>Any insights?
>>
>>
>>
>>    
>>

Reply | Threaded
Open this post in threaded view
|

Re: Interceptor usecase

Yasu
Sorry, I sent the previous email while I was still writing.
 
The point is that I am not happy with the proposed inheritance based
approach because I think AOP and Mixin are partially motivated to
avoid implementation inheritance.  The implementation inheritance will
not allow flexible code reuse.  To me, your proposed solution sounds
defeating the purpose of AOP.

If groovy supports mixin,  I would read your 'base class' as 'mixin' and
would be  happy with the solution, but I think groovy has not yet
supported the mixin (right?).

Regards,


Reply | Threaded
Open this post in threaded view
|

Re: Interceptor usecase

graemer
On 3/25/06, Yasuhiko Sakakibara <[hidden email]> wrote:

> Sorry, I sent the previous email while I was still writing.
>
> The point is that I am not happy with the proposed inheritance based
> approach because I think AOP and Mixin are partially motivated to
> avoid implementation inheritance.  The implementation inheritance will
> not allow flexible code reuse.  To me, your proposed solution sounds
> defeating the purpose of AOP.
>
> If groovy supports mixin,  I would read your 'base class' as 'mixin' and
> would be  happy with the solution, but I think groovy has not yet
> supported the mixin (right?).
Anything is possible ;-) If you really want this feature I suggest
raising an issue and it will eventually get implemented

Cheers
Graeme
>
> Regards,
>
>
>