Matt
Matt

Reputation: 5168

How should I continue a Python Social Auth Partial Pipeline

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': '', }

Key Issues

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.

However

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.

Final Questions

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

Answers (1)

omab
omab

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

Related Questions