I was reading the documentation of Python Social Auth and got curious about the section of Interrupting the Pipeline (and communicating with views).
In there, we see the following pipeline code
In our pipeline code, we would have:
from django.shortcuts import redirect
from django.contrib.auth.models import User
from social_core.pipeline.partial import partial
# partial says "we may interrupt, but we will come back here again"
@partial
def collect_password(strategy, backend, request, details, *args, **kwargs):
# session 'local_password' is set by the pipeline infrastructure
# because it exists in FIELDS_STORED_IN_SESSION
local_password = strategy.session_get('local_password', None)
if not local_password:
# if we return something besides a dict or None, then that is
# returned to the user -- in this case we will redirect to a
# view that can be used to get a password
return redirect("myapp.views.collect_password")
# grab the user object from the database (remember that they may
# not be logged in yet) and set their password. (Assumes that the
# email address was captured in an earlier step.)
user = User.objects.get(email=kwargs['email'])
user.set_password(local_password)
user.save()
# continue the pipeline
return
and the following view
def get_user_password(request):
if request.method == 'POST':
form = PasswordForm(request.POST)
if form.is_valid():
# because of FIELDS_STORED_IN_SESSION, this will get copied
# to the request dictionary when the pipeline is resumed
request.session['local_password'] = form.cleaned_data['secret_word']
# once we have the password stashed in the session, we can
# tell the pipeline to resume by using the "complete" endpoint
return redirect(reverse('social:complete', args=("backend_name,")))
else:
form = PasswordForm()
return render(request, "password_form.html")
Specially interested in the line
return redirect(reverse('social:complete', args=("backend_name,")))
which is used to redirect the user back to the pipeline using an already stablished backend.
We can see earlier in that page a condition that's used to check which backend is being used.
def my_custom_step(strategy, backend, request, details, *args, **kwargs):
if backend.name != 'my_custom_backend':
return
# otherwise, do the special steps for your custom backend
The question is, instead of manually adding it in the args=("backend_name,")
, how can the pipeline communicate the correct backend to the view?
One can simply add in the pipeline
request.session['backend'] = backend.name
and then the view becomes
backend_name = request.session['backend']
return redirect(reverse('social:complete', args=(backend_name)))