Reputation: 5168
The application I am working has an overwritten endpoint for the Python Social Auth /complete/<backend>/
endpoint.
within our urls.py
:
urlspatterns = [
...
# Override of social_auth
url(r'^api/v1/auth/oauth/complete/(?P<backend>[^/]+)/$',
social_auth_complete,
name='social_complete'),
...
]
within views.py
:
from social_django.views import complete
def social_auth_complete(request, backend, *args, **kwargs):
"""Overwritten social_auth_complete."""
# some custom logic getting variables from session (Unrelated).
response = complete(request, backend, *args, **kwargs)
# Some custom logic adding args to the redirect (Unrelated).
We are attempting to implement a partial pipeline method. The first time the endpoint is called everything works as expected.
@partial
def required_info(strategy, details, user=None, is_new=False, *args, **kwargs):
"""Verify the user has all the required information before proceeding."""
if not is_new:
return
for field in settings.SOCIAL_USER_REQUIRED_DATA:
if not details.get(field):
data = strategy.request_data().get(field)
if not data:
current_partial = kwargs.get('current_partial')
social_provider = kwargs.get('backend')
return strategy.redirect(f'.../?partial_token={partial_token}&provider={social_provider}'
else:
details[field] = data
This redirects the user to the front end in which they fill out a form which calls a POST request to orginal API api/v1/auth/oauth/complete/(?P<backend>[^/]+)/
with the following in the data:
{
'required_fieldX': 'data',
...
'partial_token': '',
}
Two things go wrong; When I pdb into required_info
there is never any data within strategy.request_data()
. There is still data within the kwargs['request'].body
and I can take the data out there.
But I am afraid that the second time around we never get into this block of code from social-core:
partial = partial_pipeline_data(backend, user, *args, **kwargs)
if partial:
user = backend.continue_pipeline(partial)
# clean partial data after usage
backend.strategy.clean_partial_pipeline(partial.token)
else:
user = backend.complete(user=user, *args, **kwargs)
I know this to be true because when I interrogate the database the original Partial object still exists as if backend.strategy.clean_partial_pipeline(partial.token)
was never called.
Why is the social_django.views.complete
not processing the POST request as expected and as it appears to be in all the example applications. Is there an issue from our overwriting it? Should I just create a separate endpoint to handle the POST request and if so how do mimic all that goes on within @psa
such that I can call backend.continue_pipeline(partial)
?
Upvotes: 2
Views: 1236
Reputation: 3701
I think there's only one issue here, and that's that the Django strategy doesn't look into request.body
when loading the request data, you can see the method in charge here. There you can see that it looks for request.GET
and/or request.POST
, but not body.
You can easily overcome this by defining your custom strategy that extends from the built-in one, and override the request_data
method to look for the values in request.body
. Then define the SOCIAL_AUTH_STRATEGY
to point to your class.
Upvotes: 1