[Seaside] Question on page redirection

Julian Fitzell seaside@lists.squeakfoundation.org
Sun, 29 Dec 2002 12:36:54 -0800


Avi Bryant wrote:
> On Sun, 29 Dec 2002 tblanchard@mac.com wrote:
> 
> 
>>When I've done WebObjects applications, I've overridden the method
>>pageWithName in session to return the login page if the cookie auth
>>token was missing.
>>
>>Whats the good bottleneck in seaside for trapping a request for a page
>>and replacing it with a login page so that I don't have to replicate
>>the test for credentials everywhere?
> 
> 
> Funny, Julian and I were just talking about that last night.  There really
> isn't a great place to do that right now.  One thing to do would be to
> write a framing component that conditionally showed either your
> application or the login page; ie, if your entry point component is
> currently, say, ToddApp, then instead make it something like
> 
> WAComponent subclass: #ToddFrame
> 	instanceVariableNames: 'main login'
> 	classVariableNames: ''
> 	poolDictionaries: ''
> 	category: 'Foo'
> 
> initialize
>   main := self containerFor: ToddApp new.
>   login := ToddLogin new.
> 
> renderOn: html
>   session hasUserInfo
>    ifTrue: [html render: main]
>    ifFalse: [html render: login]
> 
> The main problem with that approach is that the check doesn't happen until
> the response phase - if somebody requests a URL generated while a user was
> logged in, they can still trigger an action before they're asked to
> authenticate themselves.
> 
> To prevent that, you'd probably want to override
> WASession>>wrapContinuation:withReturnBlock:.  This method returns the
> blocks/continuations that are effectively the request handlers.  You
> probably want something like this:
> 
> wrapContinuation: aContinuation withReturnBlock: aBlock
>   |continue|
>   block := super wrapContinuation: aContinuation withReturnBlock: aBlock.

this should be "continue := super ..." I'm pretty sure

>   ^ [:request |
>     self hasUserInfo
>       ifFalse: [|login|
>                login := LoginPage new.
>                login withContinuationDo: [login start]].
>     continue threadSafeValue: request]
> 
> 
> Need to run, so I'll explain that bit of code later...

Well, for every request handler block, we wrap it in another block that 
first check whether the session has the auth tokens.  In the simple case 
where it already has auth information, the block just calls the block 
returned by super's implementation of the method.

In the other case, where we don't have auth info, we first create a 
LoginPage, then we execute "login withContinuationDo: [login start]]". 
#withContinuationDo: gets the current continuation and stores it in the 
component (this is used when you make a call to #answer: so we can 
return to the calling component).  #start tells the component to start 
handling the HTTP request and providing a response - this makes the 
login component the current component until it does an #answer:

Once the LoginPage had got the login info it would call #answer: and we 
would return back into the block we created above (after the 
3withContinuationDo: call), which would then need to carry on calling 
the block that was returned by the super call.

Julian


-- 
julian@beta4.com
Beta4 Productions (http://www.beta4.com)