from social_auth.backends import BACKENDS
from social_auth.utils import group_backend_by_type
from social_auth.models import User


# Note: social_auth_backends and social_auth_by_type_backends don't play nice
#       together

def social_auth_backends(request):
    """Load Social Auth current user data to context.
    Will add a output from backends_data to context under social_auth key.
    """
    return {'social_auth': backends_data(request.user)}


def social_auth_by_type_backends(request):
    """Load Social Auth current user data to context.
    Will add a output from backends_data to context under social_auth key where
    each entry will be grouped by backend type (openid, oauth, oauth2).
    """
    data = backends_data(request.user)
    data['backends'] = group_backend_by_type(data['backends'])
    data['not_associated'] = group_backend_by_type(data['not_associated'])
    data['associated'] = group_backend_by_type(data['associated'],
                                               key=lambda assoc: assoc.provider)
    return {'social_auth': data}


def backends_data(user):
    """Return backends data for given user.

    Will return a dict with values:
        associated: UserSocialAuth model instances for currently
                    associated accounts
        not_associated: Not associated (yet) backend names.
        backends: All backend names.

    If user is not authenticated, then first list is empty, and there's no
    difference between the second and third lists.
    """
    available = BACKENDS.keys()
    values = {'associated': [],
              'not_associated': available,
              'backends': available}

    # user comes from request.user usually, on /admin/ it will be an instance
    # of auth.User and this code will fail if a custom User model was defined
    if isinstance(user, User) and user.is_authenticated():
        associated = user.social_auth.all()
        not_associated = list(set(available) -
                              set(assoc.provider for assoc in associated))
        values['associated'] = associated
        values['not_associated'] = not_associated
    return values

@@ -1064,24 +1064,833 @@
 h': data%7D%0A%0A%0A
+def social_auth_by_name_backends(request):%0A    %22%22%22Load Social Auth current user data to context.%0A    Will add a social_auth object whose attribute names are the names of each%0A    provider, e.g. social_auth.facebook would be the facebook association or %0A    None, depending on the logged in user's current associations. Providers%0A    with a hyphen have the hyphen replaced with an underscore, e.g. %0A    google-oauth2 becomes google_oauth2 when referenced in templates.%0A    %22%22%22%0A    keys = BACKENDS.keys()%0A    accounts = dict(zip(keys, %5BNone%5D * len(keys)))%0A    %0A    if isinstance(request.user, User) and request.user.is_authenticated():%0A        for associated in request.user.social_auth.all():%0A            accounts%5Bassociated.provider.replace('-', '_')%5D = associated%0A    %0A    return %7B'social_auth': accounts%7D%0A%0A%0A
 def backends

Add context processor to access social auth information by backend name, useful to easily provide backend-specific functionality in your app by checking e.g. social_auth.facebook and allowing the user to publish to Facebook if it exists.