1. Sarvi Shanmugham
  2. django-socialauth

Commits

Sarvi Shanmugham  committed 18697cc

Added integration between userena and socialauth with a profile

  • Participants
  • Parent commits e50878f
  • Branches default

Comments (0)

Files changed (2)

File social_auth/backends/__init__.py

View file
 from oauth.oauth import OAuthConsumer, OAuthToken, OAuthRequest, \
                         OAuthSignatureMethod_HMAC_SHA1
 
+from django.core.exceptions import MultipleObjectsReturned
 from django.conf import settings
 from django.contrib.auth import authenticate
 from django.contrib.auth.backends import ModelBackend
 
 from social_auth.models import UserSocialAuth
 from social_auth.store import DjangoOpenIDStore
-from social_auth.signals import pre_update
+from social_auth.signals import pre_update, post_create, associated_user
 
 
 # key for username in user details dict used around, see get_user_details
 # method
 USERNAME = 'username'
+EMAIL = 'email'
 
 # OpenID configuration
 OLD_AX_ATTRS = [
                                                      uid=uid)
         except UserSocialAuth.DoesNotExist:
             user = kwargs.get('user')
+            created=False
+            updated=False
             if user is None:  # new user
                 if not getattr(settings, 'SOCIAL_AUTH_CREATE_USERS', True):
                     return None
                 username = self.username(details)
                 email = details.get('email')
-                user = User.objects.create_user(username=username, email=email)
+                try:
+                    user = User.objects.get(email=email)
+                except MultipleObjectsReturned:
+                    raise ValueError('Email id conflicts with multiple User objects')
+                except User.DoesNotExist:
+                    pass
+                if not user:
+                    user = User.objects.create_user(username=username, email=email)
+                    created = True
+
+            # Fire a pre-update signal sending current backend instance,
+            # user instance (created or retrieved from database), service
+            # response and processed details, signal handlers must return
+            # True or False to signal that something has changed. Send method
+            # returns a list of tuples with receiver and it's response
+            if created:
+                updated = filter(lambda (receiver, response): response,
+                         post_create.send(sender=self.__class__, user=user,
+                                         response=response, details=details))
+
             social_user = self.associate_auth(user, uid, response, details)
+
+            # Fire a pre-update signal sending current backend instance,
+            # user instance (created or retrieved from database), service
+            # response and processed details, signal handlers must return
+            # True or False to signal that something has changed. Send method
+            # returns a list of tuples with receiver and it's response
+            updated = filter(lambda (receiver, response): response,
+                         associated_user.send(sender=self.__class__, user=user,
+                                         response=response, details=details)) and updated
+            if updated:
+                user.save()
+
         else:
             # This account was registered to another user, so we raise an
             # error in such case and the view should decide what to do on
             for name, value in details.iteritems():
                 # do not update username, it was already generated by
                 # self.username(...) and loaded in given instance
-                if name != USERNAME and value and value != getattr(user, name,
-                                                                   value):
+                if name not in [USERNAME, EMAIL] and value \
+                   and value != getattr(user, name,value):
                     setattr(user, name, value)
                     changed = True
 

File social_auth/signals.py

View file
 """Signals"""
 from django.dispatch import Signal
 
+# post create signal
+#   This signal is sent when a user was just created.
+#   This way other apps that want to create additional profile information
+#   can create and populate their tables.
+#
+#   Handlers must return True if any value was updated/changed,
+#   otherwise must return any non True value.
+#
+#   The parameters passed are:
+#       sender:   A social auth backend instance
+#       user:     Current user instance (retrieved from db or recently
+#                 created)
+#       response: Raw auth service response
+#       details:  Processed details values (basic fields)
+post_create = Signal(providing_args=['user', 'response', 'details'])
+
 # Pre save signal
 #   This signal is sent when user instance is about to be updated with
 #   new values from services provided. This way custom actions can be
 #       response: Raw auth service response
 #       details:  Processed details values (basic fields)
 pre_update = Signal(providing_args=['user', 'response', 'details'])
+
+# assocated_user signal
+#   This signal is sent when a user instance is associated with an auth backend
+#   This way custom actions can be attached and values updated if needed 
+#   before the saving time.
+#
+#   Handlers must return True if action was taken,
+#   otherwise must return any non True value.
+#
+#   The parameters passed are:
+#       sender:   A social auth backend instance
+#       user:     Current user instance (retrieved from db or recently
+#                 created)
+#       response: Raw auth service response
+#       details:  Processed details values (basic fields)
+associated_user = Signal(providing_args=['user', 'response', 'details'])