1

I'm setting up social authentication with the package social-auth-app-django. I have the below ValueError raised when attempting to create a user when an email isn't supplied.

users.py

    if not email:
        message = "Ooops, it doesn\'t look like an email was specified. If you are signing in via one of your social media account, please ensure there is an email address associated to your account."
        raise ValueError(message)

It wasn't really necessary originally as I would handle the form validation on the front end with standard form validation. However, when integrating social sign-ins this causes an issue. In development this is great - but essentially at this stage I would like to fling the error back to an errors template which says that they must supply an email address. I believe on platforms, such as Twitter, a user can initially register without an email address associated to the account. That's where I spotted this conflict. Essentially, social-auth-app-django isn't throwing an error before this - so how at this point, do I send the user back to a specified template which I can build to handle such errors by passing them back via the context?

Looking and looking through the documentation, I can't see anything I would be confident in running with...any advise would be greatly appreciated!

1 Answers1

1

The python-social-auth module supports a pipeline - so defining a method in the end of your SOCIAL_AUTH_PIPELINE in settings.py and then implementing it in pipeline.py would give you a way to define the desired behavior in case, when your users have no email associated with their social users:

SOCIAL_AUTH_PIPELINE = (
    # any other pipeline handlers ...                                            
    'custom.signup.pipeline.prevent_without_email'
)

Then in your custom/signup/pipeline.py you'll need to implement the actual partial for prevent_without_email - You can see it here in more detail http://python-social-auth-docs.readthedocs.io/en/latest/pipeline.html

If you need a specific handler, you can use Django signals - create a signal in signals.py, emit it in pipeline.py and let the handler in callbacks.py to handle it, when an email is not specified.

dmitryro
  • 3,463
  • 2
  • 20
  • 28
  • Hi @dmitryro , my first follow up question - do I need to specify the *full* pipeline within `SOCIAL_AUTH_PIPELINE`? –  Jan 06 '18 at 20:08
  • @michael-roberts You only have to to specify those partials that really add something to the desired behavior. The order matters. Each partial method gets user as parameter, and has the capacity to decide what to do if certain conditions are not met, i.e. return other user object, handle error or anything else. The pipeline IS optional, but it does impact the way social authentication happens. – dmitryro Jan 06 '18 at 20:11
  • So, for example, I need to specify anything on user creation etc before I then begin to handle e.g., how I could use the authenticated user's third party data to build their profile? –  Jan 06 '18 at 20:14
  • If you're using FB or Google, you'll have email, avatar and other related data from those social networks (if the backends are specified and handle them) - so that data can be added to the user within pipeline - if you identify this user as legit, but some of his data is only present in social APIs (and they all differ) - you orchestrate your newly-authenticated user based on this. If for a reason you consider additional processing is needed, you can do it in signal handler (say, send a confirmation email or similar). – dmitryro Jan 06 '18 at 20:19
  • You can also create an entirely new user and associate him with this social profile, if needed. It's completely up to you within your pipeline. – dmitryro Jan 06 '18 at 20:19
  • Hmmmm. Not 100% sure how I can achieve any of this tho. I'll review the documentation some more! :) –  Jan 06 '18 at 20:21
  • Please note, that the user returned from the pipeline's partial method is not necessarily same user that was sent to the method as parameter. In an ideal scenario they are same, but not always. – dmitryro Jan 06 '18 at 20:25
  • Another quick question - can I just specify the one custom pipeline intervention ... or does SOCIAL_AUTH_PIPELINE need every step? What is the default pipeline? I guess I just need to find the right place with which to place the custom pipeline? –  Jan 06 '18 at 20:27
  • You can specify another one earlier or later (or not at all), just the order they were specified will identify what user will be there in the end and what capabilities, properties and data from social networks he will have. It can be empty, or may have the methods specified in the docs (the link I provided). What matters is if a custom method is specified, it has to be placed properly (in the beginning if the check precedes all other checks, in the end if it has to happen in the end). – dmitryro Jan 06 '18 at 20:34
  • Of course, but the link gives specific case - do you know what is the default pipeline? I can start with this and then go from there... –  Jan 06 '18 at 20:36
  • The default set they provide is pretty much common sense, so you can use it as a starting point. – dmitryro Jan 06 '18 at 20:36
  • Of course, but where is the full pipeline documented? –  Jan 06 '18 at 20:41
  • I'd say there's no full pipeline in terms of having it well-defined set of methods that absolutely must to be applied prior to successful social authentication - rather, it provides a way to orchestrate things the way you need it - it's the WHAT part, but the actual HOW (the methods called, the order they were called) - up to you. http://python-social-auth-docs.readthedocs.io/en/latest/pipeline.html is, probably, the place to refer. – dmitryro Jan 06 '18 at 20:48
  • Ok ok ok. Right - I'm probably not asking this right. I get that. So at what stage/stages does anything we add to this SOCIAL_AUTH_PIPELINE setting get organised? It's really not well documented on that link!! I'm frustrated because there should be a proper explanation! –  Jan 06 '18 at 20:53
  • Got it - The default pipeline is composed by:. My apologies :) –  Jan 06 '18 at 20:54
  • It's a flexible way that is defined and designed entirely by you. Django and Python Social Auth provide a way to secure that this will be called and you'll have a way to customize your user's policies or properties, accepted or rejected based on what the user has to show. – dmitryro Jan 06 '18 at 20:57