I've followed the instructions from this document: https://readthedocs.org/projects/python-social-auth/downloads/pdf/latest/ (page 121) and also from a similar inquiry: python-social-auth partial pipeline can not resume but I'm unable to get the email address value from the database, i.e. in my pipeline i'm not really sure how to get the value on kwargs['email'] from the below line. user = User.objects.get(email=kwargs['email'])
Can anyone for the love of god help me here? Thanks so much in advance!
Here's the setup:
forms.py
class SocialPasswordForm(forms.Form):
password = forms.CharField(max_length=32)
views.py
def get_user_password(request):
print('def post view first')
if request.method == 'POST':
print('def post view second')
form = SocialPasswordForm(request.POST)
if form.is_valid():
print('def post view third')
# 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.get('password')
#backend = request.session['partial_pipeline']['backend']
# once we have the password stashed in the session, we can
# tell the pipeline to resume by using the "complete" endpoint
print('def post view fourth')
return redirect(reverse('social:complete', args=('linkedin-oauth2',)))
else:
form = SocialPasswordForm()
return render(request, 'social_signup.html', {'form': form})
auth_pipeline.py
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
User = get_user_model()
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('social_signup')
# 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
settings.py
SOCIAL_AUTH_PIPELINE = (
# Get the information we can about the user and return it in a simple
# format to create the user instance later. In some cases the details are
# already part of the auth response from the provider, but sometimes this
# could hit a provider API.
'social_core.pipeline.social_auth.social_details',
# Get the social uid from whichever service we're authing thru. The uid is
# the unique identifier of the given user in the provider.
'social_core.pipeline.social_auth.social_uid',
# Verifies that the current auth process is valid within the current
# project, this is where emails and domains whitelists are applied (if
# defined).
'social_core.pipeline.social_auth.auth_allowed',
# Checks if the current social-account is already associated in the site.
'social_core.pipeline.social_auth.social_user',
# Make up a username for this person, appends a random string at the end if
# there's any collision.
'social_core.pipeline.user.get_username',
# Send a validation email to the user to verify its email address.
# Disabled by default.
#'social_core.pipeline.mail.mail_validation',
# Associates the current social details with another user account with
# a similar email address. Disabled by default.
'social_core.pipeline.social_auth.associate_by_email',
# Create a user account if we haven't found one yet.
'social_core.pipeline.user.create_user',
# Create the record that associates the social account with the user.
'social_core.pipeline.social_auth.associate_user',
# Populate the extra_data field in the social record with the values
# specified by settings (and the default ones like access_token, etc).
'social_core.pipeline.social_auth.load_extra_data',
# Update the user record with any changed info from the auth service.
'social_core.pipeline.user.user_details',
#CUSTOM PIPELINE
'users.auth_pipeline.collect_password',
)
...
SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = ['local_password',]
social_signup.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Home{% endblock title %}
{% block content %}
<form method="POST" class="padding">
{% csrf_token %}
{{form|crispy}}
<button type="submit">Save Password</button>
</form>
{% endblock content %}
And here's the error (pretty obvious that I'm not storing the email address from linkedin). How may I store it?
File "C:\...\auth_pipeline.py", line 24, in collect_password
print(kwargs['email'])
KeyError: 'email'
Thanks in advance. I appreciate your time.