Page MenuHomePhabricator

Differentiate between stackable and final redirects in PostLoginRedirect hook
Open, Needs TriagePublic

Description

The PostLoginRedirect gives extensions an opportunity to redirect after login (or signup). Conceptually, there are three kinds of redirects:

  • The redirect does something, invisibly to the user, then returns (e.g. CentralAuth central login). There's some minimal risk that it doesn't return because of an error / browser intervention.
  • The redirect takes the user to some UI, then returns after the user finishes (e.g. GrowthExperiments welcome survey). There is a modest risk that it doesn't return because the user abandons the flow.
  • The redirect takes the user to some location they aren't supposed to return from, replacing the default new user landing page (e.g. GrowthExperiments newcomer homepage).

The first two kinds are stackable (you could in theory do several of them in sequence), the third kind isn't. There is no way to differentiate between them currently, so it's kinda random what happens when there are multiple hook handlers. CentralAuth tries to work around this by providing a custom CentralAuthPostLoginRedirect hook, so when other extensions see CentralAuth is enabled, they can ignore the normal hook and use the custom hook instead; but that's fragile and doesn't scale.

We should have a new post-authentication redirect hook where hooks can add redirect URLs or callbacks, explicitly marked as one of the three categories above, and MediaWiki executes the invisible redirects first, the visible but non-final ones next, and logs an error if there are multiple final redirects (or maybe has some priority mechanism).

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

@daniel FYI since you are thinking about redesigning hooks - this is a somewhat common problem I think, that some handlers can coexist with other handlers and some can't, and the current system doesn't handle that well.

Another use case that came up is adding a query parameter to returntoquery (but otherwise not doing changes that could be incompatible with other handlers' intentions) and expecting that to show up on the next non-redirect response.