Saturday, June 4, 2011

Re: Shortcomings in Places

Hi Jeff,
Glad to see someone else voice the same frustrations that I had to work through with getting Places to work for me.
You are right, the pattern of substituting a login form for content is so very common.

Here are some tips on how I handled the situation:

- Have an method on the authentication state machine that determines the 'default' place to be A or B or whatever is best for the user.
I called it CurrentState.getHomePlace()

- Create an abstract subclass of Place for all places that require authentication.

For the main region ActivityMapper, try this piece of logic
@Override
public Activity getActivity(Place place) {
//---------------------
// check if the user is authenticated and the place requires it
if ( place instanceof AuthenticatedPlace && !currentState.isLoggedIn() ) {
logger.warning("unauthenticated place violation, displaying login");
LoginFormActivity loginForm = loginFormActivityProvider.get();
// add place holder to capture current login parameter to forward to...
currentState.setForwardLoginTo(place);
return loginForm;
}

if( place.equals( Place.NOWHERE ) ) {
// should redirect auto-login user to proper home place
logger.info( "place = NOWHERE" );
place = currentState.getHomePlace();
}

- and to get around the caching of the place after authenticating, 
instead of using PlaceController.goTo(), 
bypass the place caching by forcing a PlaceChangeEvent to the final destination
   eventBus.fireEvent( new PlaceChangeEvent( currentState.getForwardLoginToPlace() ));

- I also set up an auto-login function using hashed cookies which requires a round trip with the server. 
The ActivityMapper forces the display to show the login form while the auto-login pops up a dialog box saying login is in process.
When the auto-login succeeds, it clears the dialog and uses the currentState.forwardLoginToPlace to put the user in the right place.
Otherwise the user just sees the login form and proceeds from there.

- My next issue with places is validating that the object context built by the parameters (object ids) should be visible to that authenticated user. Currently my Activity.start() is doing all the checking and the code seems different for every page. Would like to see it handled in a semi-generic sense instead of down in the weeds. 



On Sat, Jun 4, 2011 at 2:47 PM, Jeff Schnitzer <jeff@infohazard.org> wrote:
I'm trying to implement a simple pattern that is *very* common in the
world of "normal" webapps:

1) Most of my application requires authentication in order to access.
2) I allow deep links to protected content.
3) When visiting a deep link, you are given a login page - after
logging in, you get the content.

I have a single-page GWT app that uses Places.  I've spent a lot of
time on this issue, and I *almost* have it working - but it's not
elegant and there are still broken edge cases.  If you want to
experience it firsthand, visit http://www.similarity.com/#matches:

The specific issues with the Places system are:

 * The default place is different in authenticated mode vs anonymous
mode.  When you are anonymous, your default place is the "hello,
stranger" place but when you're logged in, the default place is "all
about your account".  Since I can't reset the default place in the
PlaceHistoryHandler, I need to swap out the instance when I switch
modes.

 * The PlaceController has no way to reset the current place.  When an
anonymous user tries to go to the #matches: link, the place is set to
MatchesPlace (which my special handler translates into a "you must log
in first" message).  When the user logs in, I force another
handleCurrentHistory(), but it doesn't actually do anything - because
the PlaceController is already at MatchesPlace.  I'll have to swap out
the PlaceController instance when I switch modes.

And now a little rant:

All in all, this seems ludicrously difficult for something I could
have done with dozen lines of code if I wasn't trying to use the
standard GWT tools.  I feel like I've wasted a lot of time learning
the system, and what I've ultimately learned is that I would be better
off building it from scratch.

Am I the only one that thinks the Places system is WAY
over-engineered, yet not all that useful?

Jeff

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.




--
-- A. Stevko
===========
"If everything seems under control, you're just not going fast enough." M. Andretti





--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

No comments:

Post a Comment