]> git.parisson.com Git - django-social-auth.git/commitdiff
Signal user updating, still pending extra arguments request
authorMatías Aguirre <matiasaguirre@gmail.com>
Fri, 10 Dec 2010 17:39:47 +0000 (15:39 -0200)
committerMatías Aguirre <matiasaguirre@gmail.com>
Fri, 10 Dec 2010 17:39:47 +0000 (15:39 -0200)
README.rst
social_auth/backends.py
social_auth/models.py
social_auth/views.py

index e1cce535561c08ae0cf9c20c46ec4fdb474d2990..2a181db33b12407ac91aad65c40514d521585baf 100644 (file)
@@ -26,7 +26,8 @@ some features are:
     * `Facebook OAuth`_
     * `Orkut OAuth`_
 
-- Basic user data population
+- Basic user data population and signaling, to allows custom fields values
+  from providers response
 
 - Multiple social accounts association to single users
 
@@ -144,6 +145,25 @@ Installation
   it might solve your case.
 
 
+-------
+Signals
+-------
+A pre_update signal is sent when user data is about to be updated with new
+values from auth service provider, this apply to new users and already
+existent ones. This is useful to update custom user fields or `User Profiles`_,
+for example, to store user gender, location, etc. Example::
+
+    from django.dispatch import receiver
+
+    from social_auth.signals import pre_save
+    from social_auth.backends import FacebookBackend
+
+    @receiver(pre_save, sender=FacebookBackend)
+    def facebook_extra_values(sender, user, response, details):
+        user.gender = response.get('gender')
+        return True
+
+
 ------
 OpenId
 ------
index e27a02f64ec533ed29b929b2564de92b75373570..865d050f42360ecacd9d96cb0135247b795906a1 100644 (file)
@@ -11,6 +11,7 @@ from django.contrib.auth.models import UNUSABLE_PASSWORD
 
 from .models import UserSocialAuth
 from .conf import OLD_AX_ATTRS, AX_SCHEMA_ATTRS
+from .signals import pre_update
 
 # get User class, could not be auth.User
 User = UserSocialAuth._meta.get_field('user').rel.to
@@ -47,7 +48,7 @@ class SocialAuthBackend(ModelBackend):
             user = self.create_user(details=details, *args, **kwargs)
         else:
             user = auth_user.user
-            self.update_user_details(user, details)
+            self.update_user_details(user, response, details)
         return user
 
     def get_username(self, details):
@@ -95,8 +96,11 @@ class SocialAuthBackend(ModelBackend):
                                            password=UNUSABLE_PASSWORD)
 
         # update details and associate account with social credentials
-        self.update_user_details(user, details)
-        self.associate_auth(user, response, details)
+        try:
+            self.update_user_details(user, response, details)
+            self.associate_auth(user, response, details)
+        except Exception, e:
+            print str(e)
         return user
 
     def associate_auth(self, user, response, details):
@@ -124,19 +128,22 @@ class SocialAuthBackend(ModelBackend):
         """Return default blank user extra data"""
         return ''
 
-    def update_user_details(self, user, details):
+    def update_user_details(self, user, response, details):
         """Update user details with new (maybe) data"""
-        fields = (name for name in ('first_name', 'last_name', 'email')
-                        if user._meta.get_field(name))
         changed = False
-
-        for name in fields:
-            value = details.get(name)
+        for name, value in details.iteritems():
             if value and value != getattr(user, name, value):
                 setattr(user, name, value)
                 changed = True
 
-        if changed:
+        # 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
+        updated = filter(bool, pre_update.send(sender=self, user=user,
+                                               response=response,
+                                               details=details))
+        if changed or len(updated) > 0:
             user.save()
 
     def get_user_id(self, details, response):
@@ -204,6 +211,8 @@ class FacebookBackend(OAuthBackend):
 
     def get_user_details(self, response):
         """Return user details from Facebook account"""
+        import pprint
+        pprint.pprint(response)
         return {'email': response.get('email', ''),
                 'username': response['name'],
                 'fullname': response['name'],
index 84469b00f32a731e76b13290608010ffa25494f1..8ef3a96f58e8cc2c8596b5e51c20119bc9cb6c07 100644 (file)
@@ -2,7 +2,8 @@
 from django.db import models
 from django.conf import settings
 
-# If User class is overrided, it must provide the following fields:
+# If User class is overrided, it must provide the following fields,
+# or it won't be playing nicely with auth module:
 #
 #   username = CharField()
 #   email = EmailField()
index bb476891bdf5430b3a18f0a5f31ac4b05cedc2a0..5334a65498419be4fa2942471affafa09b57ca1e 100644 (file)
@@ -34,6 +34,7 @@ def complete(request, backend):
         return HttpResponseServerError('Incorrect authentication service')
     backend = BACKENDS[backend](request, request.path)
     user = backend.auth_complete()
+    print "USER:", user
     if user and user.is_active:
         login(request, user)
         url = request.session.pop(REDIRECT_FIELD_NAME, '') or \