SIGN IN SIGN UP

fix: drop live AuthSourceManager from session, store provider name only

The OAuth2 login redirect flow stashed the live AuthSourceManager
instance in flask.session via session['auth_obj'] = auth_obj, requiring
the session storage to handle arbitrary Python objects. That coupled the
auth flow to the pickle-backed session format and presented a second-
order deserialization vector if any path could influence session
contents.

The only piece of state that genuinely needs to cross the OAuth2
provider redirect is the provider name. Persist that as
session['oauth2_current_client'] (a plain str) and reconstruct a fresh
AuthSourceManager in oauth_authorize from current_app's auth-source
registry. The OAuth2 source's per-instance oauth2_current_client is
restored before login() so client selection still works on the callback.

Defensive: oauth_authorize now redirects with a flash error when the
session-state key is missing (e.g., session expired between login and
callback), instead of KeyError'ing.

Two new scenarios in test_oauth2_with_mocking.py verify (a) post-redirect
session contains the new minimal state and not a live class instance,
and (b) the callback handles missing provider state without 500.
A
Ashesh Vashi committed
64a232bc852184fe0c745b712b51883c1e79fc7c
Parent: 435752b