eevee / floof

Some kind of art site.
http://bugs.veekun.com/projects/floof
ISC License
10 stars 4 forks source link

Update to latest Persona API #8

Open eevee opened 12 years ago

eevee commented 12 years ago

I think we're still using the old one.

New one subsumes the allowPersistent option, which we weren't using but should've been, so I guess we should... figure out how that matters.

epii commented 12 years ago

I had a quick look at this.

The watch() API has Persona keeping an independent tally of which websites it thinks you are logged into. If it thinks the current site differs, it will fire off assertions every few seconds. Forever.

This is bad if, say, you have a browser cert saying you're logged in as one guy and Persona thinking you're meant to be another since floof will always authenticate in the cert's favor.

All solutions I can think of require compromises. Ugh.

See this discussion: https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.identity/mDj8oLKn8aI

eevee commented 12 years ago

Can't we just logout() them on next pageview if we detect a cert conflict?

epii commented 12 years ago

Unfortunately, logout() is overloaded as both the signal to Persona that it should consider you as wanting to be logged out and to call the onlogout function set up in navigator.id.watch. While it won't log out a cert-user, it will destroy their session.

It's also unhelpful for new users on the registration page. As they are not yet a user their loggedInUser property remains null but Persona thinks they ought to be logged in so we get infinite loops on the registration page too. But we don't want to call logout here, even if we suppress the session destruction, since we want the user to be logged in immediately after registration.

Actually, the registration page is a big problem. Even if we suppress the call to navigator.id.watch() on that page, if someone uses the "wrong" address to sign in, they'll be forever trapped there. Navigating to any other page will cause a login event with an unknown address leading back to the registration page.

I can only seem to work this out using 3/4 sentinel values:

  1. Is a cert is in use? If so, turn onlogin events into naviagator.id.logout() then immediately return from onlogout without actually POSTing to /account/logout, thus synchronising Persona state with floof's without purging the session. (There's no login button if you're already logged in, so we don't need to worry about someone firing onlogin manually via navigator.id.request().)
  2. If the current page is the registration or other auth-status-affecting page, return immediately from onlogin or onlogout events unless:
  3. An actual login or logout button has been pressed by the user, as tracked by two PERSONA_CLICKED_{IN,OUT} global flags set by the function passed to $('.persona').click() and $('.logout').click().

I believe that functionality to flag whether the onlogin or onlogout was called automatically or manually is planned for inclusion in Persona soon.

UPDATE: Haha, there are still all manner of hilarious unsolved edge cases, especially when we bring in the ability to add and remove multiple Persona identities (addresses) but I wanted to post this anyway for future reference.