0

There are questions here which answer this, but my case is different.

Instead of letting allauth create a new user I'm catching wheter or not the email exists and performing a login using

   user = User.objects.get(email=email)
   sociallogin.connect(request, user)
   social_account_added.send(
                sender=SocialLogin,
                request=request,
                sociallogin=sociallogin,
            )

But, I can't set the avatar here due to the way my conditions are setup and this may never be hit.

The alternative is in get_redirect_url from what I see, but this isn't called if I use sociallogin.get_redirect_url so it seems theres opportunity for both to be skipped.

There's a signal user_logged_in = Signal(providing_args=["request", "user"]) under account app in allauth but what if they have multiple socials connected? How would I determine the proper avatar to get...

1 Answers1

2

Is your question:

  • how to capture the avatar at signup?
  • how to choose which avatar if there are multiple social accounts?
  • how to hook the signup and instead connect the potential new user to an existing accout?

I'll address all three.

Capturing avatar at signup

My approach to this is receive the user_signed_up signal. I also extract the user name (if available) at this time.

This is the function I use:

@receiver(user_signed_up)
def set_initial_user_names(request, user, sociallogin=None, **kwargs):
    """
    When a social account is created successfully and this signal is received,
    django-allauth passes in the sociallogin param, giving access to metadata on the remote account, e.g.:

    sociallogin.account.provider  # e.g. 'twitter' 
    sociallogin.account.get_avatar_url()
    sociallogin.account.get_profile_url()
    sociallogin.account.extra_data['screen_name']

    See the socialaccount_socialaccount table for more in the 'extra_data' field.

    From http://birdhouse.org/blog/2013/12/03/django-allauth-retrieve-firstlast-names-from-fb-twitter-google/comment-page-1/
    """

    preferred_avatar_size_pixels = 256

    picture_url = "http://www.gravatar.com/avatar/{0}?s={1}".format(
        hashlib.md5(user.email.encode('UTF-8')).hexdigest(),
        preferred_avatar_size_pixels
    )

    if sociallogin:
        # Extract first / last names from social nets and store on User record
        if sociallogin.account.provider == 'twitter':
            name = sociallogin.account.extra_data['name']
            user.first_name = name.split()[0]
            user.last_name = name.split()[1]

        if sociallogin.account.provider == 'facebook':
            user.first_name = sociallogin.account.extra_data['first_name']
            user.last_name = sociallogin.account.extra_data['last_name']
            # verified = sociallogin.account.extra_data['verified']
            picture_url = "http://graph.facebook.com/{0}/picture?width={1}&height={1}".format(
                sociallogin.account.uid, preferred_avatar_size_pixels)

        if sociallogin.account.provider == 'google':
            user.first_name = sociallogin.account.extra_data['given_name']
            user.last_name = sociallogin.account.extra_data['family_name']
            # verified = sociallogin.account.extra_data['verified_email']
            picture_url = sociallogin.account.extra_data['picture']

    profile = UserProfile(user=user, avatar_url=picture_url)
    profile.save()

    user.guess_display_name()
    user.save()

That's from a Django-allauth starter example I wrote

When the user signs in that function is called. It grabs the user's name and avatar data if it can.

Choosing which avatar if there are multiple accounts

My view is that this is a user choice thing. A user can't sign up with multiple social providers in the same instant. There is always a sequence, e.g. Google first then they connect Facebook.

As such, my view is the system uses the avatar from the first social provider. The allauth UI lets the user add other social providers once they've set up the initial one (try the deo-allauth-bootrap above and you'll see).

If the user adds another social network, add some UI to choose that avatar when they want to.

Hook signup to connect existing account

This would take some experimentation but overall I feel like this is not solving a real problem.

The built-in allauth UI allows the user (once registered) to add existing social providers. That's the correct way to do it and it works out-of-the-box.

If the user signs up with another social provider then it's arguably either a mistake or they want two separate accounts.

Granted, this needs some experimentation with users to see what is the most intuitive experience.

It could be, for example, that the site notes that the user has signed in with Google before and shows the Google button slightly differently or "sign in again with Google", so the user doesn't accidentally sign up with a different social account.

Andrew E
  • 7,697
  • 3
  • 42
  • 38